Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entity Framework 4.1 Code-First and Inserting New One-to-Many Relationships

I am having trouble peristing a new object graph to the context with a one-to-many relationship. I am using the Entity Framework 4.1 release, and implementing a Code-First approach. I am using an existing SQL 2008 database and implemented a context derived from DbContext. I have two classes, Person and Address. A person can contain 0 or more Addresses, defined as such.

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; }
    }

I am trying to create a new instance of Person with two addresses. However, when I add this structure to the context and save, only the first Address in the collection is persisted. The second has the Person navigation property set to null, and is not associated with the Person object, however, the first one in the list is associated.

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();

It does not throw an exception, but the second item in the Address collection is just not saved.

Does anybody have any good ideas on why only the first would be saved? Thank you.

like image 834
connr Avatar asked Jun 23 '11 20:06

connr


People also ask

How do you create a foreign key relationship in code first approach?

To create Foreign Key, you need to use ForeignKey attribute with specifying the name of the property as parameter. You also need to specify the name of the table which is going to participate in relationship. I mean to say, define the foreign key table. Thanks for reading this article, hope you enjoyed it.

How do I remove a one to many relationship in Entity Framework?

after manual set the property,single call to "dbContext. As. Remove(someA)" work as expected!

How will you create relationship between tables in Entity Framework?

You can create such a relationship by defining a third table, called a junction table, whose primary key consists of the foreign keys from both table A and table B.


1 Answers

After hours of troubleshooting/trial and error, I've solved my problem. My POCO classes are also used in a disconnected environment, where the objects are detached from the context, modified, and then re-attached.

In order to determine which navigation property collection items were affected, I overrode the Equals and GetHashCode methods in the Address class to determine equality. Apparently this affects the ability for EF 4.1 to insert a complete collection of navigation property objects???

Here are the original equality methods which caused the issue:

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();
}

In order to correct the problem, I created a custom equality comparer for the navigation object rather than including it directly in the address class.

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();
    }
}

My context.People.Add method call worked as expected after I made this change.

If anyone knows why overriding the equality methods in the class causes EF 4.1 to only insert the first item in the collection, that would be great information.

like image 124
connr Avatar answered Sep 19 '22 13:09

connr