DbContext / ObjectDataSource更新问题

时间:2012-01-20 22:31:07

标签: entity-framework-4 objectdatasource dbcontext

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

}

当此代码运行时,我得到一个例外:

  

无法为类型实体调用成员'CurrentValues'   'Device',因为实体在上下文中不存在。添加一个   上下文的实体调用DbSet的Add或Attach方法。

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

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

1 个答案:

答案 0 :(得分:0)

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

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

上下文可能已经有FooId=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
}

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