0

我有一个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 和 repositoryCode: 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);

}

当此代码运行时,我得到一个异常:

不能为“设备”类型的实体调用成员“当前值”,因为该实体在上下文中不存在。要将实体添加到上下文中,请调用 DbSet 的 Add 或 Attach 方法。

但是,如果我执行 dbset.attach,那么我会得到实体已经存在的异常。

我不知道我能做什么,对我来说似乎是一个循环问题。我已经秃了半秃了。请帮忙。

4

1 回答 1

0

您可能已经为设备类中的导航属性创建了新实例,这些实例已经加载到上下文中。例如

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
}

或者检查上下文是否已加载导航属性,如果是,请使用该实例。

于 2012-01-21T00:28:09.467 回答