EF codefirst:我应该初始化导航属性? [英] EF codefirst : Should I initialize navigation properties?

查看:650
本文介绍了EF codefirst:我应该初始化导航属性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我看到了一些书籍(如编程实体框架code第一朱莉娅·勒曼的)像没有初始化的导航属性的定义他们的域类(POCO):

公共类用户
{
    公众诠释标识{搞定;组; }
    公共字符串用户名{获得;组; }    公共虚拟的ICollection<地址>地址{搞定;组; }
    公共虚拟许可许可{搞定;组; }
}

其他一些书籍或工具(如实体框架电动工具的)时,产生波苏斯初始化的导航属性的类,如:

公共类用户
{
    公共用户()
    {
        this.Addresses =新的IList<地址>();
        this.License =新的许可();
    }
    公众诠释标识{搞定;组; }
    公共字符串用户名{获得;组; }    公共虚拟的ICollection<地址>地址{搞定;组; }
    公共虚拟许可许可{搞定;组; }
}

Q1:哪一个更好?为什么?优点和缺点?

编辑:

公共类许可证
{
    公共许可证()
    {
        this.User =新用户();
    }
    公众诠释标识{搞定;组; }
    公共字符串键{获得;组; }
    公众的DateTime Expirtion {搞定;组; }    公共虚拟用户用户{搞定;组; }
}

Q2:在第二种方法会有堆栈溢出,如果`License`类有`User`类的引用了。这意味着我们应该有单向的参考。(?)我们应该如何决定其导航性能之一应该被删除?


解决方案

类别:没关系

有是收藏和参考导航性能之间的明显差异。参考的的一个实体。一个集合包含的实体。这意味着,初始化集合为无意义的业务逻辑方面:不定义实体之间的关联。设置一个参考呢。

所以这纯粹是preference与否,或者怎么样,你初始化嵌入列表的问题。

我个人preFER延迟初始化:

 私人的ICollection<地址> _addresses;公共虚拟的ICollection<地址>地址
{
    {返回this._addresses? (this._addresses =新的HashSet<地址>());
}

有prevents空引用异常,因此它有利于单元测试和操作的收集,但它也prevents不必要初始化。后者可以有所作为,在类有比较多的集合。缺点是,它需要相对多的水暖,电除尘器。相比于自动属性不用初始化。

引用属性:不要

参考性质的实体,所以分配一个空对象对他们来说是的有意义

更糟的是,如果你在构造函数初始化它们,EF不会物化的对象时,覆盖它们或延迟加载。直到你的积极的替换他们,他们将永远有其初始值。更糟的是,你甚至可能最终会在数据库中保存空实体!

和还有另一种效果:关系修正的不会occcur。关系修正是由EF其导航属性在连接环境中的所有实体的过程。当用户许可证分别加载,还是 User.License 将填充,反之亦然。当然,除非,如果许可在构造函数初始化。这也是真正的1:N的关联。如果地址将在其构造函数初始化用户 User.Addresses 将不会被填充!

I had seen some books(e.g programming entity framework code first Julia Lerman) define their domain classes (POCO) with no initialization of the navigation properties like:

public class User
{
    public int Id { get; set; }
    public string UserName { get; set; }

    public virtual ICollection<Address> Address { get; set; }
    public virtual License License { get; set; }
}

some other books or tools (e.g Entity Framework Power Tools) when generates POCOs initializes the navigation properties of the the class, like:

public class User
{
    public User()
    {
        this.Addresses = new IList<Address>();
        this.License = new License();
    }
    public int Id { get; set; }
    public string UserName { get; set; }

    public virtual ICollection<Address> Addresses { get; set; }
    public virtual License License { get; set; }
}

Q1: Which one is better? why? Pros and Cons?

Edit:

public class License
{
    public License()
    {
        this.User = new User();
    }
    public int Id { get; set; }
    public string Key { get; set; }
    public DateTime Expirtion { get; set; }

    public virtual User User { get; set; }
}

Q2: In second approach there would be stack overflow if the `License` class has a reference to `User` class too. It means we should have one-way reference.(?) How we should decide which one of the navigation properties should be removed?

解决方案

Collections: It doesn't matter.

There is a distinct difference between collections and references as navigation properties. A reference is an entity. A collections contains entities. This means that initializing a collection is meaningless in terms of business logic: it does not define an association between entities. Setting a reference does.

So it's purely a matter of preference whether or not, or how, you initialize embedded lists.

Personally, I prefer lazy initialization:

private ICollection<Address> _addresses;

public virtual ICollection<Address> Addresses
{ 
    get { return this._addresses ?? (this._addresses = new HashSet<Address>());
}

It prevents null reference exceptions, so it facilitates unit testing and manipulating the collection, but it also prevents unnecessary initialization. The latter may make a difference when a class has relatively many collections. The downside is that it takes relatively much plumbing, esp. when compared to auto properties without initialization.

Reference properties: Don't

Reference properties are entities, so assigning an empty object to them is meaningful.

Worse, if you initiate them in the constructor, EF won't overwrite them when materializing your object or by lazy loading. They will always have their initial values until you actively replace them. Worse still, you may even end up saving empty entities in the database!

And there's another effect: relationship fixup won't occcur. Relationship fixup is the process by which EF connects all entities in the context by their navigation properties. When a User and a Licence are loaded separately, still User.License will be populated and vice versa. Unless of course, if License was initialized in the constructor. This is also true for 1:n associations. If Address would initialize a User in its constructor, User.Addresses would not be populated!

这篇关于EF codefirst:我应该初始化导航属性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆