我想在我的一个数据类中使用下面的ICollection属性(让我们称之为“Foo”)
public class Foo
{
[Key]
public int FooId { get; set; }
public string SomeValueOrOther { get; set; }
public virtual ICollection<string> AllowedBars { get; set; }
}
我可以在使用实体上下文时添加字符串值,但它们不会“去任何地方”。换句话说,没有生成表来表示此关系,因此不会保存任何值。我期望的是一个包含两列的表,一个用于“FooId”,一个用于“AllowedBar”,EF用于将其自动映射到集合(与复杂类型一样)。
由于没有发生这种情况,我必须使用上面描述的两个属性创建一个名为“FooAllowedBar”的类。
这让我很不高兴,因为它是我在整个项目中唯一的“join”类型。当然,它可以工作,所以一个方框被勾选,但有没有人知道如何让EF为字符串集合关系生成一个表? (或int,或datetime等)
很可能,从EF上的小信息(仍然!)来看,这种功能还没有得到支持。我想接近一个明确的答案。
非常感谢, 罗布
答案 0 :(得分:17)
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<StringData> AllowedBars { get; set; }
答案 1 :(得分:3)
我知道这不是所有情况下的最佳做法,但我认为在某些情况下,在列中存储数组的逗号分隔列表是解决此问题的好方法。
条件包括:
如果一个实体中有多个字符串列表可以创建大量连接,那么这也是一个好主意。
在这些情况下,我会通过为列表提供两个属性来解决它。一个是EF使用的逗号分隔列表,另一个是访问列表中的项目时可以使用的列表,如下所示:
[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();
}
}
}
您需要将AllowedBars初始化为构造函数中的空列表。
您不需要使用[NotMapped]属性,因为无论如何都不会使用此集合,但我认为它使意图更清晰。
答案 2 :(得分:0)
这不起作用。原因是,对于关系数据库,您无法在字段中真正保存数组或集合。由于类中的每个属性都将映射到数据库字段,因此收集的唯一方法是通过一对多关系。所以你需要加入。所以它并不是EF的限制,而是关系数据库的限制。
有些人通过将XML或CSV保存到表格中的字符串字段来解决这个问题。但这被认为是非常糟糕的风格,所以不要这样做。我建议你只需要接受加入。无论如何,它并没有伤害任何人。
答案 3 :(得分:-1)
您尚未正确定义类表。假设你有两个表Foo和FooBar。还有一对多的关系,包括Foo和FooBar。然后,您将定义如下的类。
富
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; }
}
这将创建两个表,Foo有两列,FooBar有3列,包括描绘Foo和FooBars之间一对多的FooId