- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在使用以下代码使用从我的代码中收集的新信息更新实体对象。我正在使用 Entity Framework 5。
我使用以下扩展方法(作为我过去在 EF4 中使用的重新附加代码的替代方法):
public static void ApplyValues(this object currentObject, object sourceObject, System.Data.Entity.DbContext obj)
{
obj.Entry(currentObject).CurrentValues.SetValues(sourceObject);
}
问题是,当调用此方法时,SetValues
方法会尝试修改附加对象上的 EntityKey
值(显然我不希望它这样做)所以它会抛出一个错误。
我想这里有两个问题:
有没有办法阻止它尝试更新键值?
如果不是,我该如何复制过去在 EF4 中正常工作的 ObjectContext.ApplyCurrentValues()
代码?
----更新----
我之前用于EF4的代码如下:
public static System.Data.Objects.DataClasses.EntityObject ReAttach(this System.Data.Objects.ObjectContext obj, System.Data.Objects.DataClasses.EntityObject objectDetached)
{
if (objectDetached.EntityKey != null)
{
object original = null;
if (obj.TryGetObjectByKey(objectDetached.EntityKey, out original))
{
objectDetached = obj.ApplyCurrentValues(objectDetached.EntityKey.EntitySetName, objectDetached);
return objectDetached;
}
else
{
throw new ObjectNotFoundException();
}
}
else
{
return objectDetached;
}
}
最佳答案
在我看来,这个异常表明您的调用代码有问题 - 或者至少不正常。
currentObject
是一个附加实体,而 sourceObject
是(通常)一个分离的对象(不一定是实体),应该具有相同的键值(或没有键属性全部)。
确实,设置当前值与 DbContext
的工作方式不同,因为您必须显式提供当前附加的实体才能更新其当前值。使用 ObjectContext
的 ApplyCurrentValues
您不提供此实体:
objectContext.ApplyCurrentValues("MyEntitySet", sourceObject);
这是不同的,因为...
sourceObject
必须是实体,不能是任意的object
sourceObject
具有相同键值的附加实体的值在您的示例中,它会更新 currentObject
之外的另一个实体,因为 currentObject
显然不是与 sourceObject
具有相同键的实体。
如果您使用了 ObjectStateEntry.ApplyCurrentChanges
(它更接近于 DbContext
中的新版本),您将得到相同的异常:
var objectContext = ((IObjectContextAdapter)obj).ObjectContext;
var entry = objectContext.ObjectStateManager.GetObjectStateEntry(currentObject);
entry.ApplyCurrentValues(sourceObject);
EF 会在这里提示您尝试更改键值。如果 sourceObject
与 currentObject
的类型不同,它会提示,而 DbContext
会允许(这使得过程与 DbContext
在我看来更有用,因为您可以使用具有匹配属性名称的任意对象(例如 DTO)来更新实体)。
编辑
重现您在 EF 4 中使用的方法的主要问题是具有 EF 5/DbContext
的实体不是从 EntityObject
派生的,而是 POCO。因此,您没有可用的 EntityKey
来允许此方法的通用实现。
您可以做的是引入一个标记实体关键属性的接口(interface),例如:
public interface IEntity
{
int Id { get; set; }
}
您的实体类将实现此接口(interface),例如 Order
实体:
public class Order : IEntity
{
public int Id { get; set; }
public DateTime ShippingDate { get; set; }
// etc.
}
您可以为此接口(interface)创建一个带有约束的通用方法:
public static T ReAttach<T>(DbContext context, T objectDetached)
where T : class, IEntity
{
T original = context.Set<T>().Find(objectDetached.Id);
if (original == null)
throw new ObjectNotFoundException();
context.Entry(original).CurrentValues.SetValues(objectDetached);
return objectDetached;
}
如果您的实体并不总是具有 int
属性 Id
但它们的键具有不同的类型、名称或者可以是复合的,那么传递实体的键进入方法而不是使用接口(interface):
public static T ReAttach<T>(DbContext context, T objectDetached,
params object[] keyValues) where T : class
{
T original = context.Set<T>().Find(keyValues);
if (original == null)
throw new ObjectNotFoundException();
context.Entry(original).CurrentValues.SetValues(objectDetached);
return objectDetached;
}
关于c# - 如何停止尝试更改 entitykey 值的 dbentityentry.currentvalues.setvalues,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16646922/
我正在为 Mac OS X 编写程序,遇到以下问题: 在我的一个类中,有许多 bool 属性,可以使用 KVO 访问这些属性(即通过 valueForKey: 和 setValue:forKey: 方
我正在创建一个带有页面对象文件 (login.po.js) 和测试规范文件 (test.spec.js) 的 webdriver.io 自动化,但是当我调用它时它似乎无法识别该对象测试规范文件 (te
我正在尝试使用 setValue() 方法将数据保存到我的实时数据库,但它没有保存我的对象。 我尝试了一个简单的字符串,但仍然没有成功。 我的代码: FirebaseDatabase db =
我一直在谷歌应用程序脚本上为工作表编码: function basePesa(){ var sheet = SpreadsheetApp.getActiveSpreadsheet().getSh
FinalViewWithSending *newView = [[FinalViewWithSending alloc]initWithNibName:@"FinalViewWithSending"
我创建了一个自动完成和一个选项组件,当我们在输入字段中键入搜索短语时,我调用网络服务并获取数据,然后在选项组件中显示列表,但是当我从该列表中选择一个选项并将值设置为输入字段,然后 Web 服务将再次触
电子表格的 Google-apps 脚本 我有一个可变长度的对象数组。 [{}, {}]我使用 for 循环 (i=0; i
我有以下带有MutableLiveData data的ViewModel和另一个从ones派生的LiveData data,其方式是仅当data.number等于1时才更新其值。 class Dumm
我在 Mac OS X 10.6.8、wxPython 2.9.3.1 和 64 位 Python v2.7.2 下运行以下代码: import wx class MyFrame(wx.Frame):
我会在他注册时将用户数据保存到 firebase,但是有一个问题,如果他创建了 Auth 帐户然后在保存他的信息之前失去了连接,这意味着他将得到没有任何个人资料信息的电子邮件\密码。 所以问题是如果他
我创建了一个自动完成和一个选项组件,当我们在输入字段中键入搜索短语时,我调用网络服务并获取数据,然后在选项组件中显示列表,但是当我从该列表中选择一个选项并将值设置为输入字段,然后 Web 服务将再次触
我们目前有一个按钮,第一次按下时会添加一个节点,如下/Users/UID/Interests/childByAutoID/"value",再次按下时会删除该节点上的值。第一次单击按钮时,值将添加到节点
我在使用 Swift 编写的 iOS 应用程序中使用 Firebase。 static func createUserRecord(uid: String, user: User){
大家好,我是 swift 的新手,在我的应用程序中,我声明了一个这样的字典: var imageDict : Dictionary = [:] 我想像这样为该字典设置值: imageDict.setV
我已经使用代码创建了RadioGroup var radios = new Ext.form.RadioGroup({ columns : 2, items: [
这个问题已经有答案了: Xcode - How to fix 'NSUnknownKeyException', Reason: "… this class is not key value codin
如何使用 RTTI 设置枚举字段的值? 即 type TCPIFileStatus= (fsUnknown, fsProcessed); TTest = class FStatus:
我帮助维护一个 Google 电子表格,其中通过 HTML 表单添加新数据。 添加新数据时,新数据的插入点取决于表单字段之一(申请接收日期)。 该脚本查找工作表中应插入数据的位置并执行 3 件事: 在
我正在编写的程序使用许多注册表项来存储一些重要信息。为了确保程序的第一个方法中存在所有注册表项,我测试注册表项是否存在,如果不存在则创建它们并使用默认值。 这是我的代码: RegistryKey R
我正在学习 Extjs 并遇到问题,当我尝试将新文本附加到项目时,我收到错误 tf.setValue 不是函数 getValue 也是如此。当我尝试 setVisible 时,它的工作原理应该是这
我是一名优秀的程序员,十分优秀!