我有一个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,那么我得到实体已经存在的异常。
我不知道我能做什么,对我来说似乎是一个循环问题。我已经半秃了,把头发拉过来。请帮忙。
答案 0 :(得分: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
}
或检查上下文是否已加载导航属性,如果是,则使用该实例。