Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent Entity Framework to automatically attach entities

I'm using the Entity Framework, and it's entities are used are Database representation AND business object.
So it means that some entities that are manipulated should always stay detached from the context.

I managed to read and write data from the database but I have a small problem when updating:
I have a table "Stock" which is linked to one table "Warehouse".

The current process is this one (simplified, but the spirit remains, there are more fields):

  • a new object Stock is created and its fields are filled with some values (date...)
  • the current Warehouse (object pulled for the entire request from the database) is associated to the Stock object
  • the object is sent to the DAL method which work is to save it.
  • The DAL method checks if the Stock item already exist for the day (same date, depot and same type) in the database
  • If it exist, the method updates the volume from the pulled object and save the changes.
  • Else, the new Stock object is inserted.

The problem here is that when I create the new Stock object and associate it to the Warehouse, the object EntityState is automatically set to "Added". So when I perform a SaveChanges() and the Stock already exist, the line is updated AND a new Stock line is added...
What I would want is to keep the new Stock object Detached until I attach it myself. I don't want that it happens automatically.

The only solution I found is to Detach the new object from the context before saving if the object already exist.
I could also Detach() the Warehouse object but that's not a satisfying solution I think as in the real case there are more items to associate and I'm not sure that's a good idea to play with Attach() and Detach() on them.
In this case, until I "Add" it to the context myself, the object is only a "Transport" object and I'd like it to stay out of the context.

Any idea on how I could keep the Stock object detached ?


Code (it may be a little incorrect, I wrote it by memory) :

Stock stk = new Stock();
stk.Date = DateTime.Now;
stk.Volume = 100;          //so far stk is "Detached" and that's cool.
stk.Warehouse = CurrentWarehouse; //stk become "Added" and that's less cool.

DAL.Stock.Instance.Save(stk);

In Save():

var existing = (from s in Context.CurrentContext.Stock
where s.Warehouse.WarehouseId == stk.Warehouse.WarehouseId && s.Date == stk.Date && s.Type == 2
select s).FirstOfDefault();

if(existing != null)
{
    existing.Volume = stk.Volume;
    Context.CurrentContext.Detach(stk); //I find it a stupid workaround !!!!!!
}
else
{
    Context.CurrentContext.AddToStock(stk); //what I would want to do.
}

Context.CurrentContext.SaveChanges()
like image 763
Julien N Avatar asked Nov 20 '09 16:11

Julien N


1 Answers

You probably just want to set the MergeOption to an appropriate value. NoTracking would keep everything in a detached state, and allow you to perform your manual work. There are probably other ways to do this, but I'm doing something similar by setting MergeOption to detached.

http://msdn.microsoft.com/en-us/library/system.data.services.client.dataservicecontext.mergeoption.aspx

like image 128
Tim Ridgely Avatar answered Nov 15 '22 00:11

Tim Ridgely