Entity Framework 4.0 + One to Many Relations

In this blog post I’m going to show you something that should be really simple but entity Frameworks makes it a little bit difficult.  Removing items from a One to Many relationship. I love the Entity Framework and Code First but sometimes you get really bogged down because of very small things that take a lot of time researching.

I’m currently using EF4 in a small Project called Yamma when I ran into the problem described below: (http://yamma.codeplex.com). Yamma is an application for managing your bank account and expenses. It’s not done yet.. but when it is I’ll post about it. Now lets get on with or problem description:

The below example uses Code First CTP5 as a way of creating a database

Data model:

The following data model is used in this example:

blogPicture

The order class shown above have a list of OrderItems which have their own OrderId containing the order they belong to. The following datacontext is used for this example:

namespace test
{
    public class TestDataCOntext: DbContext
    {
        public DbSet<Order> Orders { get; set; }
    }
}

Now lets get to the interesting part suppose I have the following code:

    public class testExample
    {
        private TestDataContext con = new TestDataContext();

        public void doStuff()
        {
            Order o = new Order();
            OrderItem it = new OrderItem();
            OrderItem it2 = new OrderItem();
            OrderItem it3 = new OrderItem();
            o.Items.Add(it);
            o.Items.Add(it2);
            o.Items.Add(it3);
            con.Orders.Add(o);
            con.SaveChanges();
            //lets make it break by removing an order from the collection and save it again
            MakeItBreak(o, it);

        }

        public void MakeItBreak(Order o, OrderItem it)
        {
            o.Items.Remove(o);
            con.SaveChanges();
        }
    }
}

The code above gives an error when using Code First CTP5 the exception thrown is the following:

System.InvalidOperationException: The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable. When a change is made to a relationship, the related foreign-key property is set to a null value. If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted.

The reason for this is that when you remove the orderitem from the list and try to save it tries to update the item like shown below:

OrderItemId OrderId
1 NULL

Code first put a relation on the table saying that the orderid field could not be null so it throws the exception mentioned earlier.

How to fix it:

This is simple, the first step is extending the DataContext class with a DbSet<OrderItems> like shown below:

namespace test
{
    public class TestDataCOntext: DbContext
    {
        public DbSet<Order> Orders { get; set; }
        public DbSet<OrderItems> OrderItems { get; set; }
    }
}

Also the make it break function need fixing so here’s the new one:

 public void MakeItWork(Order o, OrderItem it)
 {
            o.Items.Remove(o);
            con.OrderItems.Remove(o);
            con.SaveChanges();
 }

This works because after removing it from the list, it also removes the orderitem from the database by calling the remove statement on the OrderItems DbSet.

At this moment I can hear some people think and say.. ‘What a stupid way of doing things’.  Why should EF4 leave the item when I say that it should remove it. The reason that I can think is that this is a small error within Code First and i; think that it will be fixed in the next release.

Leave a comment

Your email address will not be published.

*