使用构造函数初始化POCO实体

时间:2011-08-11 14:44:59

标签: c# entity-framework constructor poco

我有2个POCO课程:

(他们的摘录):

public class Note
{
    public int Id { get; set; }
    public int CategoryId { get; set; }

    public virtual Category Category { get; set; }

    public Note(int categoryId)
    {
    }
}

public class Category
{
    public int Id { get; set; }

    public virtual ICollection<Note> Notes { get; set; }
}

这是一个1:n关系,Note只有一个Category,每个类别都有很多Notes

我希望每个Entity上都有一个构造函数来初始化所有属性(这比使用Object Initializer更好。)

但是如果我在Note上使用构造函数,我不知道如何将Note与其类别“绑定”。

如果我将CategoryId传递给构造函数,则类别将为null。如果我通过Category并手动分配ID,则类别将为null

那么,有没有办法可以使用构造函数初始化实体并获取链接到我的注释的类别?

修改

如您所见,我在Note类上有一个构造函数。我的问题是:我是否必须传递categoryId,整个Category项? (如果我将某些东西归咎于虚拟财产,ReSharper就会哭泣。)

如果我将categoryId传递给对象,则不会链接实体。

3 个答案:

答案 0 :(得分:12)

你的努力有什么意义?它几乎没用,因为:

  • 您仍需提供参数较少的构造函数,因为EF需要它
  • 您的自定义构造函数永远不会被EF
  • 使用
  • 如果您想使用延迟加载,则需要导航属性virtual
  • 从构造函数中分配虚拟属性是错误的,因为虚拟代码可以在派生类中重写,并且构造函数可以触发尚未初始化的派生类中的逻辑执行(父构造函数首先执行)。在您的确切情况下,这不是问题,但任何人都可以派生您的类并覆盖Category属性,这将成为一个问题。这完全是错误的做法。

初始化程序是解决所有问题的解决方案,那么为什么要使用参数化构造函数呢?您应该定义您的优先事项。如果您必须使用延迟加载,请放弃使用参数化构造函数,或者使用必须在构造函数外部配置Category的事实。如果不需要延迟加载,只需从virtual中删除Category关键字,然后根据需要使用参数化构造函数。

答案 1 :(得分:0)

一旦附加了实体并将其保存到上下文或由上下文返回,就会填充虚拟属性。

如果您确实希望Category不为null,则应设置id(或导航属性)并将更改应用于上下文。

答案 2 :(得分:-2)

如果它们是POCO,则将CategoryId公开为只读属性:

public class Note
{
    public int Id { get; set; }
    public int? CategoryId { get { return Category == null ? (int?)null : Category.Id; } }
    public virtual Category Category { get; set; }
}