SM.*_*SM. 3 entity-framework-4
我有一个具有很多属性的对象.一堆这些大对象将被插入到数据库中,但只有一个属性在更改.将要更改的属性不是主键.第一次SaveChanges成功,但后续的失败,"ObjectStateManager中已存在具有相同键的对象.....".这是代码中的流程:
//create the entity and set the properties that don't change
TheLargeObject obj = new TheLargeObject();
obj.Prop1 =
obj.Prop2 =
...
obj.Prop20 =
//create a list of values that differ between each entity
List<int> validIds = new List<int>();
private static void SaveToDatabase(TheLargeObject obj, List<int> validIds)
{
foreach (int id in validIds)
{
//this is the only property that changes
obj.KeyId = id;
//make a copy - do we really need this?
TheLargeObject newobj = new TheLargeObject();
newobj = obj;
using(Entities objContext = new Entities())
{
objContext.TheLargeObjects.AddObject(newobj); //ERROR: An object with the same key already exists in the ObjectStateManager.
objContext.SaveChanges();
}
}
}
Run Code Online (Sandbox Code Playgroud)
我刚刚开始使用EF4,所以我可能会以错误的方式解决这个问题.谢谢
我不确定你在这里做什么.主要是这句话让我困惑:
一堆这些大对象将被插入到数据库中,但只有一个属性在更改.
一个怎样的新对象(即插入)是变化的?如果它是新的,有什么可以改变的?
模型中的所有实体都有一个EntityKey,它通常是数据库端的主键.
我认为你在做什么.AddObject,当你应该做的时候.Attach.
以下是INSERT新对象的方法:
var newFoo = new Foo();
ctx.Foos.AddObject(newFoo);
newFoo.SaveChanges();
Run Code Online (Sandbox Code Playgroud)
以下是更新现有对象的方法:
var existingFoo = ctx.Foos.SingleOrDefault(x => x.Id == 1); // or however you want to get it
existingFoo.Name = "Changed foo";
newFoo.SaveChanges();
Run Code Online (Sandbox Code Playgroud)
或者,如果您有一个分离的实体:
var existingFoo = new Foo();
existingFoo.Name = "Foo name";
ctx.Foos.Attach(existingFoo);
ctx.SaveChanges();
Run Code Online (Sandbox Code Playgroud)
所以,我认为在您的示例中,您的代码应该只是:
objContext.TheLargeObjects.Attach(newObject);
objContext.SaveChanges();
Run Code Online (Sandbox Code Playgroud)
简而言之,如果您有一个积极的实体已存在于数据库中,并且您已手动构建实体,请使用.Attach.如果您有品牌打击新对象,请使用.AddObject.
但是,为了安全起见 - 您可以再次获取对象,进行所需的更改,然后执行.SaveChanges().
.Attach通常用于无状态场景,例如网站,其中对象不会在请求之间保留在图形中,因此需要进行更改.Attach,或者在进行更改之前再次检索对象.
希望这能为你清除它.
| 归档时间: |
|
| 查看次数: |
3588 次 |
| 最近记录: |