实体框架4.1代码优先并插入新的一对多关系

时间:2011-06-23 20:32:27

标签: entity-framework-4.1

我无法将一个新的对象图固定到具有一对多关系的上下文中。我正在使用Entity Framework 4.1发行版,并实现Code-First方法。我正在使用现有的SQL 2008数据库并实现了从DbContext派生的上下文。我有两个班,人和地址。一个人可以包含0个或更多地址,定义如下。

public class Person 
    {
        public Person()
        {
            Addresses = new List<Address>();
        }

        public int PersonId { get; set; }
        ***Additional Primitive Properties***

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

    }

public class Address 
    {
        public int AddressId { get; set; }
        public int AddressTypeId { get; set; }
        ***Additional Primitive Properties***

        public int PersonId { get; set; }
        public virtual Person Person { get; set; }
    }

我正在尝试使用两个地址创建一个Person的新实例。但是,当我将此结构添加到上下文并保存时,只会保留集合中的第一个地址。第二个将Person导航属性设置为null,并且不与Person对象关联,但是,列表中的第一个关联。

var person = new Person();

var mailingAddress = new Address() { AddressTypeId = 1 };
person.Addresses.Add(mailingAddress);

var billingAddress = new Address() { AddressTypeId = 2 };
person.Addresses.Add(billingAddress);

context.People.Add(entity);
context.SaveChanges();

它不会抛出异常,但是地址集合中的第二项不会被保存。

有没有人对为什么只保存第一个有什么好主意?谢谢。

3 个答案:

答案 0 :(得分:10)

经过数小时的故障排除/反复试验,我解决了我的问题。 我的POCO类也用于断开连接的环境中 对象与上下文分离,修改,然后重新附加。

为了确定哪些导航属性集合项受到影响,我覆盖了 Address类中的Equals和GetHashCode方法用于确定相等性。显然这会影响EF 4.1插入完整的导航属性对象集合的能力???

以下是导致此问题的原始相等方法:

public override bool Equals(object obj)
{
    Address address = obj as Address;
    if (address == null) return false;
    return address.AddressId == this.AddressId;
}

public override int GetHashCode()
{
    return this.AddressId.GetHashCode();
}

为了解决问题,我创建了一个自定义相等比较器 用于导航对象,而不是直接将其包含在地址类中。

public class AddressEqualityComparer : IEqualityComparer<Address>
{
    public bool Equals(Address address1, Address address2)
    {
        if (address1.AddressId == address2.AddressId)
            return true;
        else
            return false;
    }

    public int GetHashCode(Address address)
    {
        return address.AddressId.GetHashCode();
    }
}

我的context.People.Add方法调用在我做出此更改后按预期工作。

如果有人知道为什么覆盖类中的等式方法会导致 EF 4.1仅插入集合中的第一个项目,即 很棒的信息。

答案 1 :(得分:1)

正如已经暗示的那样,这是因为GetHashCode方法正在使用所有兄弟姐妹的ID,在Entity Framework的比较点将为0。只是评论出来,你会很高兴。

我有同样的问题,这篇文章让我知道了。我甚至懒得查看我的EntityBase代码......它已经很老了,直到现在还没有永远改变。

非常感谢您的研究!

答案 2 :(得分:0)

这是尝试添加代码的另一种方法。值得一试。这段代码可能不准确,我是徒手打字的。

var person = new Person();

person.Addresses.Add(new Address()
{
   AddressTypeId = 1
}),
new Address()
{
   AddressTypeId = 2
});

context.People.Add(entity);
context.SaveChanges();
相关问题