在.NET实体框架中调用SaveChanges时出现InvalidOperationException

时间:2009-06-17 17:48:21

标签: c# .net entity-framework

我正在尝试学习如何使用实体框架,但我遇到了一个我无法解决的问题。 我正在做的是,我正在浏览我拥有的电影列表,并将每个电影插入一个简单的数据库。

这是我正在使用的代码

private void AddMovies(DirectoryInfo dir)
{
    MovieEntities db = new MovieEntities();
    foreach (DirectoryInfo d in dir.GetDirectories())
    {
        Movie m = new Movie { Name = d.Name, Path = dir.FullName };
        db.AddToMovies(movie);
    }
    db.SaveChanges();
}

当我这样做时,我在db.SaveChanges()上得到一个读取的异常。

  

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

我无法找出导致此问题的原因。 我的数据库表包含三列 Id int autoincrement
名称nchar(255)
路径nchar(255)

更新: 我检查了我的edmx文件,SSDL部分按照建议使用StoreGeneratedPattern =“Identity”。我也跟着博客文章,试图在CSDL中添加ClientAutoGenerated =“true”和StoreGenerated =“true”。这导致编译错误(错误5:不允许'ClientAutoGenerated'属性。)。由于博客文章是从2006年开始的,它有一个后续帖子的链接,我认为它已被更改。

但是,我无法阅读后续帖子,因为它似乎需要一个msdn帐户。

8 个答案:

答案 0 :(得分:10)

我找到了解决方案。

发生了什么事,当我创建我的表时,我忘了添加主键并将(Is Identity)属性设置为yes。然后我创建了我的实体模型并得到了这个错误。

我回去修复了我的数据库表,但我仍然讨厌奇怪的异常。最终解决问题的方法是删除实体并在修复表后重新创建它。

没有例外:)

答案 1 :(得分:7)

上次我尝试了以下代码,我说它工作正常

bs.SuspendBinding();
Data.SaveChanges();
bs.ResumeBinding();

我今天告诉你的重要事情是:

1-如果我们使用上面的代码来暂停绑定,我们必须做更多的代码来修复很多场景,比如集合中丢失的索引和主细节绑定

2-如果我们使用以下代码而不是上面的代码,我们将看到异常消失,并且每个东西都可以,无需编写更多代码

        Data.SaveChanges(System.Data.Objects.SaveOptions.None);

我希望这能解决你的类似问题

谢谢你的朋友

答案 2 :(得分:6)

这个异常似乎告诉你,在Id列中的几行中你有相同的值,它应该只有唯一值,因为它是一个键列。实体框架可以通过两种方式处理此类列:您(客户端)生成唯一值,或者服务器生成唯一值。在您的情况下,允许服务器生成自动增量密钥似乎是合乎逻辑的。

您是否在SSDL文件中为Id列设置了StoreGeneratedPattern密钥?

以下是this blogpost的示例:

<EntityType Name="rooms" Key="id">
    <Property Name="id" Type="int" Nullable="false" 
              StoreGeneratedPattern="Identity" />
    <Property Name="name" Type="nvarchar" Nullable="false" MaxLength="50" />
</EntityType>

答案 3 :(得分:2)

System.Data.Objects.SaveOptions.None

这解决了问题,但我想知道使用一个或其他选项有什么区别。

答案 4 :(得分:1)

如果绑定了绑定源,则应调用suspendbinding:

        bs.SuspendBinding();
        Data.SaveChanges();
        bs.ResumeBinding();

答案 5 :(得分:0)

检查您的任何属性中是否缺少主键, 如果是,则创建它们,然后执行“从数据库更新模型”

这应该解决问题

答案 6 :(得分:0)

另外,检查是否将另一列的“Is Identity”属性设置为“yes”,并在其中插入重复的值。

答案 7 :(得分:0)

我遇到类似的问题,表格关系跨越三个级别,如客户 - &gt;订单 - &gt;订单详细信息,带有oracle 12C Auto-ID触发器,用于密钥生成。使用SaveChanges()进行广告投放System.InvalidOperationException

解决方案:扩充函数SaveChanges(System.Data.Objects.SaveOptions.None)可防止系统在对象图的状态中使用临时EntityKeys,并避免结果异常。