Я работаю над приложением MVC3 и создал свои классы POCO из своей базы данных с помощью генератора кода DbContext. Все идет хорошо, пока я не застрял в этой ситуации. Обратите внимание, что я использую шаблон репозитория, и я использую для каждой сущности выделенный репозиторий, получаю ли новый экземпляр DbContext.
Сейчас я в такой ситуации:
объект A имеет отношение один ко многим с B (A может иметь одно или несколько B) объект B имеет отношение многие к одному с C (C может иметь одно или несколько B) объект B имеет отношение многие к -один с D (D может иметь один или несколько B)
Я должен добавить новый объект B, учитывая, что объекты C и D еще существуют, поэтому я должен только выполнить связь, а объект A можно создать или обновить. В частности, учтите, что A — клиент, а B — подписки (C и D — свойства виртуальных объектов в B).
Теперь, если я попытаюсь сохранить, у меня есть дубликаты в таблицах C и D, при этом управление объектом, похоже, работает. Итак, я подумал, что мне следует отсоединить объекты, прежде чем делать отношение, но когда я вызываю SaveChanges(), я получаю эту ошибку:
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.
Вот код:
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();
}
А вот метод добавления и сохранения репозитория клиента:
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();
}
Я также пытался использовать это для объектов C и D.
((System.Data.Entity.Infrastructure.IObjectContextAdapter)dbContext).ObjectContext.Refresh(System.Data.Objects.RefreshMode.StoreWins, entry);
И полученная ошибка
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.
Я заметил, что в CTP5 была добавлена опция AsNoTracking(), я пытался ее использовать, но ничего! Я также проверил режим параллелизма для всех свойств, участвующих в операции, и все они установлены на None. Я закончил идеи :(!
Любая помощь будет оценена! Спасибо!