已成功提交对数据库的更改,但更新对象上下文时发生错误

时间:2013-06-03 20:07:06

标签: entity-framework entity-framework-5

我有一个使用EF5,.NET 4和SQL Server 2008的winforms应用程序。我在数据库中有以下表\ entity。创建表的T-SQL如下所示。

CREATE TABLE [Admin].[StandardTerms](
    [StdTermID] [int] IDENTITY(1,1) NOT NULL,
    [Name] [nvarchar](50) NOT NULL,
    [Description] [nvarchar](100) NOT NULL,
 CONSTRAINT [PK_StandardTerms] PRIMARY KEY CLUSTERED 
(
    [StdTermID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]

我在表单上使用BindingSource对象,该对象链接到允许用户创建新标准术语的数据网格。当用户创建新的标准术语并尝试保存它时,我收到以下错误。

  

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

标准术语表的主键是自动生成的整数。我检查了SSDL,并确保在实体上定义了StoreGeneratedPattern。

<EntityType Name="StandardTerms">
    <Key>
        <PropertyRef Name="StdTermID" />
    </Key>
    <Property Name="StdTermID" Type="int" Nullable="false" StoreGeneratedPattern="Identity" />
    <Property Name="Name" Type="nvarchar" Nullable="false" MaxLength="50" />
    <Property Name="Description" Type="nvarchar" Nullable="false" MaxLength="100" />
</EntityType>

奇怪的是,只有当我从网格中创建标准术语时才会发生这种情况。我可以使用我的存储库创建一个,它工作得很好。我甚至可以创建完全相同的绑定源结构,它没有错误。此时我很难过。有没有人对这里发生的事情有任何想法?

4 个答案:

答案 0 :(得分:2)

我终于找到了我的问题,因为我怀疑这是我做的蠢事。在我的模型中,我正在构建查询,加载值并返回BindingList。我做的是修复它是检查我的BindingList是否为null,如果是我构建了查询,加载了值并创建了绑定列表。

原始代码

public BindingList<StandardTerm> StandardTerms
{
    get
    {
        _uow.StandardTerms.FindAll().Load();
        _standardTerms = _uow.StandardTerms.GetBindingList();
    }
}

更正代码

public BindingList<StandardTerm> StandardTerms
{
    get
    {
        if (_standardTerms == null)
        {
            _uow.StandardTerms.FindAll().Load();
            _standardTerms = _uow.StandardTerms.GetBindingList();
        }

        return _standardTerms;
    }
}

我的存储库类实现了GetBindingList方法,如下所示。

protected DbSet<T> _set;
public BindingList<T> GetBindingList()
{
    return _set.Local.ToBindingList();
}

我的实体都依赖于以下MDSN文章中描述的ObservableListSource。

EF DataBinding with WinForms

答案 1 :(得分:1)

当我忘记将其中一个多列主键字段标记为[Key]

时出现此错误

答案 2 :(得分:0)

另一个产生此类错误消息的选项是INSTEAD OF触发器添加一个没有Id列的结果集。例如:http://i.stack.imgur.com/3GXUw.png

通过请求以下内容的实体框架将不会获得Id列。

insert [dbo].[Xxxx]([XxxxId], [FirstName], [LastName], [ProfileUrl], 
        [LastModified], [PictureUrl], [Headline])
values (@0, @1, @2, null, @3, null, null)
select [Id], [Revision]
from [dbo].[Xxxx]
where @@ROWCOUNT > 0 and [Id] = scope_identity()

修复是将Id列添加到RS中。

答案 3 :(得分:0)

我定义了一个触发器和序列,但是忘记将StoreGeneratedPattern设置为Identity