Entity framework 已成功提交对数据库的更改,但更新对象上下文时出错
我有一个winforms应用程序,它使用EF5、.NET4和SQLServer2008。我在数据库中有下表\实体。创建表的T-SQL如下所示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
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似乎在检索项目创建后分配给该项目的密钥时遇到问题。