Как сохранить связанные новые объекты, полученные из разных DBContext CTP5

Я работаю над приложением 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. Я закончил идеи :(!

Любая помощь будет оценена! Спасибо!


person stuzzo    schedule 04.03.2011    source источник


Ответы (1)


На самом деле я решил сам использовать при загрузке метод AsNoTracking() и перед сохранением сущностей меняю состояние на Unchanged.

//On loading
Context.Object.AsNoTracking().SingleOrDefault(l => l.Property == Property);

//On saving
Object.State = EntityState.Unchanged;
Object.SaveChanges();

Надеюсь, это поможет кому-то.

person stuzzo    schedule 04.03.2011