实体框架多对多关系初始化ICollection

时间:2018-05-18 20:01:45

标签: c# entity-framework model many-to-many relationship

举个例子,我们有以下情况:我有一个名为StandardEngineeredModel的类,它具有ModelNumber,VoltageInput,VoltageOutput等属性。

我还有一个名为Fuse的类,它具有Designator,Rating和Type等属性。在我的数据库模型中,这两个类与彼此之间存在多对多的关系,StandardEngineeredModel可以包含 MANY 保险丝,并且保险丝可以包含在 MANY 不同的StandardEngineeredModels中。请参阅下面的代码。

public class StandardEngineeredModel
{
    StandardEngineeredModel()
    {
        Fuses = new List<Fuse>();
    }

    [Key]
    public string ModelNumber { get; set; }
    public int VoltageInput { get; set; }
    public string VoltageOutput {get;set;}

    public ICollection<Fuse> Fuses { get; set; }
}

public class Fuse
{
    [Key,Column(Order = 0)]
    public string Designator { get; set; }
    [Key, Column(Order = 1)]
    public string Rating { get; set; }
    [Key, Column(Order = 2)]
    public string Type { get; set; }

    public ICollection<StandardEngineeredModel> StandardEngineeredModels { get; set; }
}

所以我的问题是在构造函数中初始化集合的部分:对于我的StandardEngineeredModel,使用列表初始化Fuses是有意义的。但是在我的Fuse类中,初始化ICollection对我来说真的没有意义,因为我通常会将熔丝分配给StandardEngineeredModel,而不是将StandardEngineeredModel分配给保险丝。

这样做是否有任何问题,我没有看到?这会给我带来哪些类型的问题?我在我的一些应用程序中使用了EF,但还没有需要多对多关系,所以我正在寻找一些关于此的一般建议。

提前致谢!

2 个答案:

答案 0 :(得分:-1)

您在技术上不必在构造函数中初始化集合,但是您需要知道它们将为null(特别是因为您没有使用启用延迟加载的virtual关键字)和你需要在整个应用程序中检查它 - 否则,你可能会在意想不到的地方获得null异常。

答案 1 :(得分:-1)

  

但在我的Fuse类中,初始化ICollection对我来说真的没有意义,因为通常我会将熔丝分配给StandardEngineeredModel,而不是将StandardEngineeredModel分配给保险丝。

您上面说的是真的,但我认为,您将这些实体模型域模型混淆。在您的域模型中,您可以在StandardEngineeredModel中使用方法:

public void AssignFuses(List<Fuse> fuses)

但是在你的Fuse中,你将不会有这样的方法:

public void AssignStandardEngineeredModels(
    List<StandardEngineeredModel> sems) // makes no sense

但是,您的域模型客户端(客户端是指其他类或开发人员)可能需要从Fuse导航到他们被分配到的StandardEngineeredModel,因此他们将如何做它?那么Fuse类需要一个只读List<StandardEngineeredModel>来帮助解决这个问题。

现在回到你的实体模型:

  

这样做是否有任何问题,我没有看到?这会给我带来哪些类型的问题?

如果你有一个包含其他类的类是一个好习惯,那么初始化它们是很好的。为什么?因为我们想对自己和其他开发者好。考虑一下:

public class A
{
    public List<string> SomeThings{ get; set; }
    public A(){}
}

我正在使用你的类,我看不到代码,因为我正在使用DLL。我这样做:

var a = new A();
a.SomeThings.Add("1");

我编译,我将代码提供给QA,他们忘记测试这个非常具体的案例,然后进入制作和BAM!

因此,请遵循良好做法并对其进行初始化。我不确定EF是否会因为没有初始化而失败,所以也许你可以测试并弄明白。

一个建议

我建议不要使用后缀 Model 命名实体模型。如果我的客人是正确的,你可能正在为MVC这样做,并认为这是你的模型。但问题是你正在设计你的表名,意图它将在MVC中使用。如果不是怎么办?此外,有些情况下,此模型不足以成为MVC中的模型,并且可能需要其他属性。