EF Code First不为ICollection 生成表

我想在我的一个数据类中使用下面的ICollection属性(让我们称之为“Foo”)

public class Foo { [Key] public int FooId { get; set; } public string SomeValueOrOther { get; set; } public virtual ICollection AllowedBars { get; set; } } 

我可以在使用实体上下文时添加字符串值,但它们不会“去任何地方”。 换句话说,不会生成表来表示此关系,因此不会保存任何值。 我期望的是一个包含两列的表,一个用于“FooId”,一个用于“AllowedBar”,EF用于自动将其映射到集合(与复杂类型一样)。

由于没有发生这种情况,我必须使用上面描述的两个属性创建一个名为“FooAllowedBar”的类。

这让我很不高兴,因为它是我在整个项目中唯一的“join”类型。 当然,它可以工作,所以只勾选一个方框,但是有人知道如何让EF为字符串集关系生成一个表吗? (或int,或datetime等)

很可能,从EF上的那些小信息(仍然!)来看,这种function还没有得到支持。 我想接近一个确定的答案。

非常感谢,Rob

EF只能与实体类一起使用。 每个实体类都必须具有已定义的主键,因此您的方案中的最小值为:

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

或者更糟

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

现在您可以定义StringData的集合以将其映射为相关表:

 public virtual ICollection AllowedBars { get; set; } 

我知道这不是所有情况下的最佳实践,但我认为有些情况下,在列中存储数组的逗号分隔列表是解决此问题的好方法。

条件包括:

  • 列表不会很长
  • 您无需根据该列表中的值搜索实体

如果一个实体中有多个字符串列表会产生大量连接,这也是一个好主意。

在这些情况下,我会通过为列表提供两个属性来解决它。 一个是EF使用的逗号分隔列表,另一个是访问列表中的项目时可以使用的列表,如下所示:

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

您需要将AllowedBars初始化为构造函数中的空列表。

您不需要使用[NotMapped]属性,因为无论如何都不会使用此集合,但我认为它使意图更清晰。

这不行。 原因是,对于关系数据库,您无法在字段中真正保存数组或事物集合。 由于类中的每个属性都将映射到数据库字段,因此收集的唯一方法是通过一对多关系。 所以你需要加入。 所以它不是EF的限制,而是关系数据库的限制。

有些人通过将XML或CSV保存到表中的字符串字段来解决这个问题。 但这被认为是非常糟糕的风格,所以不要这样做。 我建议你只需要接受加入。 无论如何,它并没有伤害任何人。

您尚未正确定义类表。 假设你有两个表Foo和FooBar。 还有一对多的关系,包括Foo和FooBar。 然后,您将定义如下的类。

 public class Foo { public int FooId { get; set; } public string SomeValue { get; set; } public virtual ICollection 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; } } 

这将创建两个表,Foo有两列,FooBar有3列,包括描绘Foo和FooBars之间一对多的FooId