0

In the NBA basketball game I want to store play-by-play data. One Game has its StartTime, two Teams and the list of plays. Each Play has its occurrence in time and (depends on the play) different properties. There are 8 different play types, for example: "Rebound", "FieldGoalAttempt":

Rebound:

  • team
  • player
  • reboundType

Field Goal Attempt:

  • team

  • shootingPlayer

  • assistingPlayer

  • blockingPlayer

  • shotType

  • distanceFeet

  • points

  • location

  • result

As you can see, these two are totally different plays - and there are 6 more types. Which brings me to my first problem.

Question 1: How do I implement it in C#?

My idea is to create a type Play, and then 8 classes representing play types, like Rebound, FieldGoalAttempt, JumpBall like this:

public class Play
{
    public int PlayId { get; set; }
    public int GameId { get; set; }
    public int PlayerId { get; set; }

    public Rebound Rebound { get; set; }
    public FieldGoalAttempt FieldGoalAttempt { get; set; }
    public Turnover Turnover { get; set; }
    public Foul Foul { get; set; }
    ...
    public JumpBall JumpBall { get; set; }

    public Game Game { get; set; }
    public Player Player { get; set; }
} 

But I wasn't sure if this is a "code smell". I had a few more ideas: A list of objects? or a custom built C# class that acts like "Union"? So first question is How should I handle this situation in C#? Is my first idea good?

Question 2: After all, I want to store these plays in the database. In my architecture I use Models that represents tables in the database. For my logic I create Service, so models are "anemic" which some people call "anti-pattern", but I don't want to talk about it. I have Services for my logic and it works for me.

If I decide to create Union like class - How do I store these plays in the database?

Ish Thomas
  • 2,270
  • 2
  • 27
  • 57
  • Its unclear what you are asking, although you question was descriptive enough, it seems like it has little to do with DDD, its hard to know what these nested types are (what type of data they are) – TheGeneral Feb 19 '20 at 04:36
  • @MichaelRandall one sec, let me clarify – Ish Thomas Feb 19 '20 at 04:38
  • Like `C++` union or `TypeScript` union types? There is nothing like that in `C#`. – vasily.sib Feb 19 '20 at 04:40
  • You could use F# to model your domain model and then reference your domain lib from your application code. In C# they would be subtypes. You can focus on best domain model, or best table model if you are using your domain models as ORM entities. If you get both that is just a coincidence of the domain. – Devon Burriss Feb 19 '20 at 07:37
  • _But I wasn't sure if this is a "code smell"_ - If you not sure, then it should be ok. You will notice a "code smell" when you will actually recognise some code which will probably bring problems during further development. Continue with design you have and when you actually start struggling with problems - fix it. – Fabio Feb 20 '20 at 08:22

1 Answers1

0

You can use inheritance for this. Like:

public class BasePlay
{
    public DateTimeOffset StartTime { get; set; }
    public Team TeamA { get; set; }
    public Team TeamB { get; set; }
}

public class JumpBallPlay : BasePlay
{
    public string ExtraProperty1 { get; set; }
}

public class FieldGoalAttemptPlay : BasePlay
{
    public string ExtraProperty2 { get; set; }
}

Then, you can map this classes with EntityFramework using Table Inheritance:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<BasePlay>()
        .HasDiscriminator<string>("PlayType")
        .HasValue<JumpBallPlay>("jumpBall")
        .HasValue<FieldGoalAttemptPlay>("fieldGoalAttemptPlay");
}

All your objects will be stored in the same table, but mapped to a different columns (with some common for all columns from BasePlay, see Shared columns section). Extra column PlayType will contain the type of a play.

vasily.sib
  • 3,871
  • 2
  • 23
  • 26
  • Did you consider the idea of 9 different tables (8 tables for 8 different types of play and 1 table `Play` with common columns + 8 FK columns with navigation to particular play type)? Obviously only on FK will not be null, others will be null. Do you think 1 table with (~40 columns) to server all play types is better? – Ish Thomas Feb 19 '20 at 05:07
  • 1 table is better then 9 in SQL Server point of view. Also, table with 8 FK scares me:) – vasily.sib Feb 19 '20 at 05:10
  • I got you. The only concern I have is that "one table" makes possible (from the db perspective) to have a play "jump ball" with "assistingPlayer" and let say "result=2points" - which doesn't make sense - but the database allows it. Should I be worry about this? – Ish Thomas Feb 19 '20 at 05:14
  • Do you worry about what will happen if a row will contain values for properties which doesn't exist in concrete type? EF will ignore all other columns except ones that are mapped to the type defined by discriminator column. – vasily.sib Feb 19 '20 at 05:17
  • What about size of the database? That's a lot of columns that will be null – Ish Thomas Feb 19 '20 at 05:30
  • If your table will contains a large (dozens of billions) amout of rows - this can be an issue, otherwise you shouldn't care about 10-20 extra KB used by database files. – vasily.sib Feb 19 '20 at 05:43
  • You may also find [this](https://stackoverflow.com/questions/3731172/how-much-size-null-value-takes-in-sql-server) usefull – vasily.sib Feb 19 '20 at 05:44