Entity framework 已成功提交对数据库的更改,但更新对象上下文时出错

Entity framework 已成功提交对数据库的更改,但更新对象上下文时出错,entity-framework,entity-framework-5,Entity Framework,Entity Framework 5,我有一个winforms应用程序,它使用EF5、.NET4和SQLServer2008。我在数据库中有下表\实体。创建表的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

我有一个winforms应用程序,它使用EF5、.NET4和SQLServer2008。我在数据库中有下表\实体。创建表的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]
protected DbSet<T> _set;
public BindingList<T> GetBindingList()
{
    return _set.Local.ToBindingList();
}
我在表单上使用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>


奇怪的是,只有当我从网格中创建一个标准术语时,才会发生这种情况。我可以使用我的存储库创建一个,它工作得很好。我甚至可以创建完全相同的绑定源结构,并且它可以正常工作。在这一点上,我被难住了。有人对这里可能发生的事情有什么想法吗?

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

原始代码

public BindingList<StandardTerm> StandardTerms
{
    get
    {
        _uow.StandardTerms.FindAll().Load();
        _standardTerms = _uow.StandardTerms.GetBindingList();
    }
}
公共绑定列表标准术语
{
得到
{
_uow.StandardTerms.FindAll().Load();
_standardTerms=\u uow.standardTerms.GetBindingList();
}
}
正确代码

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

        return _standardTerms;
    }
}
公共绑定列表标准术语
{
得到
{
如果(_standardTerms==null)
{
_uow.StandardTerms.FindAll().Load();
_standardTerms=\u uow.standardTerms.GetBindingList();
}
返回标准条款;
}
}
MyRepository类实现了GetBindingList方法,如下所示

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]
protected DbSet<T> _set;
public BindingList<T> GetBindingList()
{
    return _set.Local.ToBindingList();
}
protecteddbset\u集;
公共绑定列表GetBindingList()
{
返回_set.Local.ToBindingList();
}
我的实体都依赖下面的MDSN文章中描述的ObservableListSource


另一个产生此类错误消息的选项是,不要在触发器上添加没有Id列的resultset。例如:

而实体框架通过请求以下内容将无法获取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中。

当我忘记将多列主键字段中的一个标记为
[key]
时,我得到了这个错误。我定义了一个触发器和序列,但是忘记设置为
Identity

在将StdTermID发送到数据库之前是否设置了它?否。StdTermID列不会在网格中显示给用户,我也不会在代码中对它做任何操作。我假设(这通常会让我陷入麻烦)任何新的标准术语实体都会以默认值0创建。如错误消息所述,该项将添加到数据库表中。EF似乎在检索项目创建后分配给该项目的密钥时遇到问题。