EF Code First not generating table for ICollection

前端 未结 4 663
旧时难觅i
旧时难觅i 2020-12-07 01:28

I would like the below ICollection property in one of my data classes (let\'s call it \"Foo\")

public class Foo
{
    [Key]
    public int FooId { get; set;          


        
相关标签:
4条回答
  • 2020-12-07 01:34

    This won't work. The reason for this is, that with relational databases, you can't really save arrays or a collection of things in fields. And since every property in your class will be mapped to a database-field, the only way to collections is via a one to many relationship. So you need the join. So it's not really a limitation of EF, but of relational databases.

    There are people that solve that by saving XML or CSV to string fields in the table. But this is considered very bad style, so don't do it. I recommend you just have to accept the join. It's not hurting anyone anyway.

    0 讨论(0)
  • 2020-12-07 01:47

    I know this is not best practice in all cases, but I think there are cases where storing a comma seperated list of your array in a column is a good way to solve this problem.

    Conditions include:

    • The list is not going to be long
    • You don't need to search for entities based on the values in that list

    It could also be a good idea if one entity has multiple string lists in it that would create lots of joins.

    In those cases I would solve it by having two properties for the list. One being the comma seperated list used by EF and the other a list that you can use when accessing the items in the list like this:

    [NotMapped]
    public List<String> AllowedBars { get; set; }
    
    /// <summary>
    /// Comma seperated list of AllowedBars
    /// </summary>
    public String AllowedBarsList
    {
        get { return String.Join(",", AllowedBars); }
        set
        {
            if (String.IsNullOrWhiteSpace(value))
            {
                AllowedBars.Clear();
            }
            else
            {
                AllowedBars = value.Split(',').ToList();
            }
        }
    }
    

    You need to initialise AllowedBars to be an empty list in the constructor.

    You don't need to use the [NotMapped] attribute as this collection won't be used anyway, but I think it makes the intent clearer.

    0 讨论(0)
  • 2020-12-07 01:55

    EF can only work with entity classes. Each entity class must have defined primary key so the minimum in your scenario is:

    public class StringData
    {
        public int Id { get; set; }
        public string Data { get; set; }
    }
    

    or worse

    public class StringData
    {
        [Key]
        public string Data { get; set; }
    }
    

    Now you can define collection of StringData to map it as related table:

    public virtual ICollection<StringData> AllowedBars { get; set; }
    
    0 讨论(0)
  • 2020-12-07 01:58

    You have not define your class tables appropriately. Suppose you have two Tables Foo and FooBar. And there is a one-to-many relationship b/w Foo and FooBar. Then you will define the classes as below.

    Foo

    public class Foo
    {
        public int FooId { get; set; }
        public string SomeValue { get; set; }
    
        public virtual ICollection<FooBar> FooBars { get; set; } 
    }
    

    FooBar

    public class FooBar
    {
        public int FooBarId { get; set; }
        public string SomeProperty { get; set; }
        public int FooId { get; set; }
    
        public virtual Foo Foo { get; set; } 
    }
    

    This will create two tables with Foo having two columns and FooBar having 3 columns including the FooId depicting one-to-many between Foo and FooBars

    0 讨论(0)
提交回复
热议问题