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