尝试使用EF 4迭代添加对象时,System.InvalidOperationException [英] System.InvalidOperationException when trying to iteratively add objects using EF 4

查看:358
本文介绍了尝试使用EF 4迭代添加对象时,System.InvalidOperationException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题与这一个非常相似。但是,该问题的解决方案:

This question is very similiar to this one. However, the resolution to that question:


  1. 似乎不适用,或

  2. 有些嫌疑人,似乎不是一个很好的解决问题的方法。

基本上,我正在迭代一个通用列表对象,并插入它们。使用MVC 2,EF 4与默认代码生成。

Basically, I'm iterating over a generic list of objects, and inserting them. Using MVC 2, EF 4 with the default code generation.

foreach(Requirement r in requirements)
{
    var car = new CustomerAgreementRequirement();
    car.CustomerAgreementId = viewModel.Agreement.CustomerAgreementId;
    car.RequirementId = r.RequirementId;
    _carRepo.Add(car); //Save new record
}

而Repository.Add()方法: p>

And the Repository.Add() method:

public class BaseRepository<TEntity> : IRepository<TEntity> where TEntity : class
{
    private TxRPEntities txDB;
    private ObjectSet<TEntity> _objectSet;        

    public void Add(TEntity entity)
    {
        SetUpdateParams(entity);
        _objectSet.AddObject(entity);
        txDB.SaveChanges();
    }

我应该注意到,我已经成功地使用了Add()方法我的代码为单插入;这是我第一次尝试使用它来迭代地插入一组对象。

I should note that I've been successfully using the Add() method throughout my code for single inserts; this is the first time I've tried to use it to iteratively insert a group of objects.

错误:


System.InvalidOperationException:数据库的更改为提交成功,但更新对象上下文时发生错误。 ObjectContext可能处于不一致的状态。内部异常消息:AcceptChanges不能继续,因为对象的键值与ObjectStateManager中的另一个对象冲突。确保键值在调用AcceptChanges之前是唯一的。

System.InvalidOperationException: The changes to the database were committed successfully, but an error occurred while updating the object context. The ObjectContext might be in an inconsistent state. Inner exception message: AcceptChanges cannot continue because the object's key values conflict with another object in the ObjectStateManager. Make sure that the key values are unique before calling AcceptChanges.

如先前的问题所述,EntityKey设置为True,StoreGeneratedPattern =身份。正在插入的实际表是关系表,其中包括一个标识字段和两个外键字段。错误始终发生在第二个插入,无论该特定实体是否已被插入,并且我可以确认这些值总是不同,就数据库而言,没有关键的冲突。我的怀疑是它与在实际插入之前设置的临时entitykey有关,但我不知道如何确认,也不知道如何解决它。

As stated in the prior question, the EntityKey is set to True, StoreGeneratedPattern = Identity. The actual table that is being inserted into is a relationship table, in that it is comprised of an identity field and two foreign key fields. The error always occurs on the second insert, regardless of whether that specific entity has been inserted before or not, and I can confirm that the values are always different, no key conflicts as far as the database is concerned. My suspicion is that it has something to do with the temporary entitykey that gets set prior to the actual insert, but I don't know how to confirm that, nor do I know how to resolve it.

我的直觉是,将先前的问题解决方案,将SaveOptions设置为None不会是最好的解决方案。 (见以前的讨论这里

My gut feeling is that the solution in the prior question, to set the SaveOptions to None, would not be the best solution. (See prior discussion here)

推荐答案

我已经在使用循环的存储库中遇到了这个问题,并认为这可能是由某些奇怪的种族状况。我做的是重构一个UnitOfWork类,所以repository.add()方法是严格添加到数据库,但不存储上下文。因此,存储库仅负责收集本身,并且该收集的每个操作都发生在工作单元的范围内。

I've had this issue with my repository using a loop as well and thought that it might be caused by some weird race-like condition. What I've done is refactor out a UnitOfWork class, so that the repository.add() method is strictly adding to the database, but not storing the context. Thus, the repository is only responsible for the collection itself, and every operation on that collection happens in the scope of the unit of work.

存在的问题是:In一个循环,你跑出的内存快速与EF4。所以你需要定期存储更改,每次保存后我都不要存储。

The issue there is that: In a loop, you run out of memory damn fast with EF4. So you do need to store the changes periodically, I just don't store after every save.

public class BaseRepository:IRepository其中TEntity:class
{
private TxRPEntities txDB;
private ObjectSet _objectSet;

public class BaseRepository : IRepository where TEntity : class { private TxRPEntities txDB; private ObjectSet _objectSet;

public void Add(TEntity entity)
{
    SetUpdateParams(entity);
    _objectSet.AddObject(entity);
}

public void Save()
{
    txDB.SaveChanges();
}

然后你可以做一些像

foreach(Requirement r in requirements)
{
    var car = new CustomerAgreementRequirement();
    car.CustomerAgreementId = viewModel.Agreement.CustomerAgreementId;
    car.RequirementId = r.RequirementId;
    _carRepo.Add(car); //Save new record
    if (some number limiting condition if you have thousands)
        _carRepo.Save(); // To save periodically and clear memory
}

_carRepo.Save();

注意:我不像这样的解决方案,但是我追捕周围试图找到为什么在其他地方工作时,为什么事情会发生循环,这是我想出来的最好的。

Note: I don't really like this solution, but I hunted around to try to find why things break in a loop when they work elsewhere, and that's the best I came up with.

这篇关于尝试使用EF 4迭代添加对象时,System.InvalidOperationException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆