I'm working on a MVC3 application and I created my POCO classes from my database with the DbContext Code Generator. All goes fine until I got stuck in this situation. Note that I use the repository pattern and I use for every entity a dedicated repository whether get a new instance of the DbContext.
Now, I'm in this situation:
object A has a relation one-to-many with B (A can have one or many B) object B has a relation many-to-one with C (C can have one or many B) object B has a relation many-to-one with D (D can have one or many B)
I should add a new object B, consider that object C and D are yet existing, so I must only do the relation and the object A can be created or updated. In the specific consider that A is customer and B is subscriptions (C and D are virtual objects properties in B).
Now If I try to save I got duplicates in C and D tables, while the management of the object seems to work. So, I thinked that I should detach the entities before do the relation, but when I call the SaveChanges() I got this error:
Store update, insert, or delete statement affected an unexpected number of rows (0).开发者_如何学编程 Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries.
Here's the code:
Customer customer = customerRepository.Get(ID);
if (customer == null)
{
customer = new Customer();
customer.Email = Request.Form["Email"].ToString();
}
Subscription subscription = new Subscription();
subscription.Active = true;
subscription.DateSubscription = DateTime.Today;
Object C = objectCRepository.Get(Request.Form["IDObjectC"]);//Get C object from database
Object D = objectDRepository.Get(Request.Form["IDObjectD"]);//Get D object from database
if (C != null)
{
//I tried also to detach the objects before adding to subscription
subscription.C = C;
subscription.D = D;
customer.Subscriptions.Add(subscription);
if (customer.IDCustomer == 0)
customerRepository.Add(customer);
else
UpdateModel(customer);
customerRepository.Save();
}
And here the add and the save method of the customer repository:
public override void Add(Cliente cliente)
{
db.Cliente.Add(cliente);
}
public override void Save()
{
foreach (var entry in db.ChangeTracker.Entries()
.Where(e => e.State == EntityState.Modified || e.State == EntityState.Added || e.State == EntityState.Unchanged || e.State == EntityState.Detached))
{
string state = ObjectContext.GetObjectType(entry.Entity.GetType()).Name + " " + entry.State.ToString();
if (ObjectContext.GetObjectType(entry.Entity.GetType()).Name.Equals("C") || ObjectContext.GetObjectType(entry.Entity.GetType()).Name.Equals("D"))
{
entry.State = EntityState.Unchanged;
}
dbContext.SaveChanges();
}
I tried also to use this for objects C and D.
((System.Data.Entity.Infrastructure.IObjectContextAdapter)dbContext).ObjectContext.Refresh(System.Data.Objects.RefreshMode.StoreWins, entry);
And the error received is
The element at index 0 in the collection of objects to refresh has a null EntityKey property value or is not attached to this ObjectStateManager.
I noticed that in CTP5 was added the option AsNoTracking(), I tried to use it, but nothing! I checked also the Concurrency mode for every properties involved in the operation and all are set to None. I finished ideas :(!
Any help would appreciated! Thanks!
Actually I solved myself using on loading the AsNoTracking() method and before saving the entities I change the state to Unchanged.
//On loading Context.Object.AsNoTracking().SingleOrDefault(l => l.Property == Property); //On saving Object.State = EntityState.Unchanged; Object.SaveChanges();
Hope this helps someone.
精彩评论