Проблема обновления DbContext / ObjectDataSource - PullRequest
0 голосов
/ 21 января 2012

У меня есть ObjectDataSource, который вызывает методы бизнес-уровня для обновления EF и сохранения.У меня есть эта странная проблема.Ниже приводится разметка ODS:

<asp:ObjectDataSource ID="odsDeviceForm" runat="server"  ypeName="Spectre.BLL..DeviceManager"
  DataObjectTypeName="Model.Device" SelectMethod="GetById" 
  InsertMethod="Insert" oninserting="OnItemInserting" UpdateMethod="UpdateEx" 
  oninserted="OnItemInserted" onupdated="OnItemUpdated" 
  onupdating="OnItemUpdating" onobjectcreated="OnOdsObjectCreated" 
  onselected="OnOdsItemSelected"  ConflictDetection="CompareAllValues" OldValuesParameterFormatString="orig{0}"   >
  <SelectParameters>
    <asp:SessionParameter Name="primaryKey" SessionField="SelectedDeviceId" Type="Int32" />
  </SelectParameters>

Ниже приводится BLL и репозиторийКод: BLL:

public void UpdateEx(T entity, T origentity)
{
  try
  {
    repository.Update(origentity, entity);
    repository.Save();
  }
  catch (Exception)
  {
    throw;
  }
}

Репозиторий:

public void Update(T orig, T newEntity)
{
  myContext.Entry<T>(newEntity).CurrentValues.SetValues(newEntity);

}

Когдакод запускается, я получаю исключение:

Элемент «CurrentValues» не может быть вызван для объекта типа «Устройство», поскольку объект не существует в контексте.Чтобы добавить сущность в контекст, вызовите метод Add или Attach из DbSet.

Но если я сделаю dbset.attach, то получу исключение, что сущность уже существует.

У меня естьне знаю, что я могу сделать, кажется круговой проблемой для меня.Я стал наполовину лысым, натягивая свои волосы на это.Пожалуйста, помогите.

1 Ответ

0 голосов
/ 21 января 2012

Возможно, вы создали новые экземпляры навигационных свойств в вашем классе устройств, которые уже загружены в контекст.Например,

device.Foo = new Foo { Id = 1 };
context.Devices.Attach(device);

Контекст может уже иметь экземпляр Foo с Id=1.Поэтому, когда вы присоединяете Device, он также пытается присоединить Foo, но не удается, потому что существует соответствующий экземпляр, который уже отслеживается контекстом.

Если возможно, попробуйте установить только скалярные свойства.

device.FooId = 1;
context.Devices.Attach(device);

Чтобы определить, загружен ли экземпляр Foo

var foo = context.ObjectStateManager
  .GetObjectStateEntries(EntityState.Added | EtityState.Modified | EntityState.Unchanged)
  .Select(s => s.Entity).OfType<Foo>().SingleOrDefault(f => f.Id == device.FooId);

if (foo != null)
{
   // foo is loaded
}

Или проверьте, загрузил ли контекст навигационное свойство, и если это так, используйте этот экземпляр.

...