Hi all,
I'm having a huge problem deleting records from a database using Entity Framework 4.0...
Let's say I have an
Order Object
with
OrderDetail Objects
.
Let's say my
Order
looks as follows:
public partial class Order
{
public bool RemoveProductFromOrder(int productId)
{
IEnumerable<OrderDetail> details = this.OrderDetails.Where(d => d.ProductId == productId)
details.ToList().ForEach(d => this.OrderDetails.Remove(d));
return details.Any();
}
}
Pretty straightforward I'd say.
So what is the problem? Whenever I remove an
OrderDetail
this way the only thing that happens is that the reference of the
OrderDetail
to the
Order
is set to
null
. So what happens when I call
ObjectContext.SaveChanges()[
^]? I get an
Exception
saying that
OrderDetail.OrderId
is non-nullable and should have a value.
What is the solution to this? Pretty 'easy'...
I should hook up an event handler to the
AssociationChanged Event[
^] of
Order.OrderDetails
and remove the
OrderDetail
from the
ObjectContext[
^] manually, like so:
this.OrderDetails.CollectionChanged += (sender, e) =>
{
if (e.Action == CollectionChangeAction.Remove)
{
context.DeleteObject(e.Element);
}
};
Now the problem is that I don't have a reference to my
ObjectContext
in every
Entity[
^]. I could pass a reference to every
Entity
, but that is not very elegant. It is also disaster waiting to happen since almost every business object would have access to data stuff.
I could hook up the event handler in the same
Class
where I keep my
ObjectContext
reference, but that would mean I have to loop through all
Orders
I fetch from the database(or use the
ObjectMaterialized Event[
^]) and hook up the event. Plus there is no way to know when a new
Order
was created (of course I could know, but polling every possible way for object creation and hooking up the event is also a disaster waiting to happen).
Last, I could handle the
ObjectContext.SavingChanges Event[
^] and check the
ObjectStateManager[
^] for
OrderDetails
that do not have an
OrderId
... But this is also a very nasty solution!
Is there a clean, elegant and maintainable solution to this problem? I couldn't find it and I'm about to pull my hair out (and I've got a lot!) over this problem... Any help is appreciated. Thanks!