Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entity Framework Code First and Collections of Primitive Types

When creating POCO classes that contain collections of primitive types and are persisted by EF Code First, the best advice I have found so far is to create a new class that has an ID plus the primitive type:

Entity Framework and Models with Simple Arrays

If I now have several classes that require properties of type ObservableCollection<string> and replace them with ObservableCollection<EntityString> (where EntityString is a custom type with an Id and a string property), I end up with a table EntityString that has multiple foreign key columns, one for each property of type ObservableCollection<EntityString> across all concrete types with such properties.

This leads to a bloating of mostly-null foreign key columns in the EntityString table.

One approach would be to create a subclass of EntityString and use the Table per Type model for those subclasses. However, that requires making awkward changes to the object model simply to accommodate Entity Framework.

Questions:

  • Is the encapsulating type the best way to manage Collection<PrimitiveType>?
  • If so, what are the pro's and con's of allowing multiple (many) foreign key columns vs. creating custom tables per type (at the cost of an awkward model)?
like image 506
Eric J. Avatar asked Nov 30 '11 23:11

Eric J.


People also ask

How do I use code first in Entity Framework?

Step 1 − First, create the console application from File → New → Project… Step 2 − Select Windows from the left pane and Console Application from the template pane. Step 3 − Enter EFCodeFirstDemo as the name and select OK. Step 4 − Right-click on your project in the solution explorer and select Manage NuGet Packages…

What is Entity Framework core code first?

The Code First approach enables you to define an entity model in code, create a database from the model, and then add data to the database. MySQL Connector/NET is compatible with multiple versions of Entity Framework Core.

How do I create a schema in Entity Framework code First?

As with any code-first schema customization, you can do this by using the entity classes' attributes or through the DbModelBuilder API. With data annotations, you can use the optional second parameter of the Table attribute to specify the schema name. The code in Figure 3 implements this change in the model.


1 Answers

Promoting simple type to entity is one option. If you want to use that new primitive type entity in more relations it is better to completely remove navigation properties from that entity and use independent association (no FK properties).

public class StringEntity
{
    public int Id { get; set; }
    public string Text { get; set; }
}

and mapping:

modelBuilder.Entity<Foo1>().HasMany(f => f.Strings).WithOptional();
modelBuilder.Entity<Foo2>().HasMany(f => f.Strings).WithOptional();

In database you will get new nullable FK per related principal - there is no way to avoid it except create special StringEntity class per principal (don't use inheritance for that because it affects performance).

There is an alternative:

public class StringEntity
{
    public int Id { get; set; }
    public List<string> Strings { get; private set; }

    public string Text 
    {
        get
        {
            return String.Join(";", Strings);
        }

        set
        {
            Strings = value.Split(";").ToList();
        }
    }   
}

In this case you don't need related entity type (and additional table) but your entity is polluted with additional property Text which is only for persistence.

like image 91
Ladislav Mrnka Avatar answered Oct 21 '22 11:10

Ladislav Mrnka