English 中文(简体)
EF4:在具有触发器的视图中插入时ObjectContext不一致
原标题:EF4: ObjectContext inconsistent when inserting into a view with triggers

I get an Invalid Operation Exception when inserting records in a View that uses “Instead of” triggers in SQL Server with ADO.NET Entity Framework 4. The error message says:

{“已成功提交对数据库的更改,但在更新对象上下文时出错。ObjectContext可能处于不一致的状态。内部异常消息:定义EntityKey的键值对不能为null或为空。参数名称:record”}

@ at System.Data.Objects.ObjectContext.SaveChanges(SaveOptions options)
  at System.Data.Objects.ObjectContext.SaveChanges()

在这个简化的例子中,我创建了两个表,Contacts和Employers,以及一个视图Contacts_x_Employeers,它允许我同时向这两个表中插入行或从中检索行。表只有一个Name和一个ID属性,视图基于这两个属性的联接:

CREATE VIEW [dbo].[Contacts_x_Employers]
AS
SELECT dbo.Contacts.ContactName, dbo.Employers.EmployerName
FROM dbo.Contacts INNER JOIN dbo.Employers 
ON dbo.Contacts.EmployerID = dbo.Employers.EmployerID

并且有这个触发器:

Create TRIGGER C_x_E_Inserts
   ON  Contacts_x_Employers
   INSTEAD of INSERT
AS 
BEGIN
    SET NOCOUNT ON;

    insert into Employers (EmployerName)
    select i.EmployerName 
        from inserted i
    where  not i.EmployerName in 
    (select EmployerName from Employers)

    insert into Contacts (ContactName, EmployerID)
    select i.ContactName, e.EmployerID 
    from inserted i inner join employers e
    on i.EmployerName = e.EmployerName;

END
GO

.NET代码如下所示:

using (var Context = new TriggersTestEntities()) { Contacts_x_Employers CE1 = new Contacts_x_Employers(); CE1.ContactName = "J"; CE1.EmployerName = "T"; Contacts_x_Employers CE2 = new Contacts_x_Employers(); CE1.ContactName = "W"; CE1.EmployerName = "C"; Context.Contacts_x_Employers.AddObject(CE1); Context.Contacts_x_Employers.AddObject(CE2); Context.SaveChanges(); // line with error }

SSDL和CSDL(视图节点):

<EntityType Name="Contacts_x_Employers">
   <Key>
    <PropertyRef Name="ContactName" />
<PropertyRef Name="EmployerName" />
   </Key>
<Property Name="ContactName" Type="varchar" Nullable="false" MaxLength="50" />
<Property Name="EmployerName" Type="varchar" Nullable="false" MaxLength="50" />
 </EntityType>

<EntityType Name="Contacts_x_Employers">
  <Key>
     <PropertyRef Name="ContactName" />
     <PropertyRef Name="EmployerName" />
   </Key>
   <Property Name="ContactName" Type="String" Nullable="false" MaxLength="50" Unicode="false" FixedLength="false" />
   <Property Name="EmployerName" Type="String" Nullable="false" MaxLength="50" Unicode="false" FixedLength="false" />
</EntityType>

The Visual Studio solution and the SQL Scripts to re-create the whole application can be found in the TestViewTrggers.zip at ftp://JulioSantos.com/files/TriggerBug/. I appreciate any assistance that can be provided. I already spent days working on this problem.

问题回答

当我试图用“而不是插入”和“而不是更新”触发器在视图中插入一行时,我偶然发现了同样的问题。

我想我找到了一个解决方案:当visualstudio的向导将视图放在模型中时,它会在一些属性(可能是实体的键)上添加StoreGeneratedPattern=“Identity”。

在常规表上生成请求时,此属性告诉实体框架期望返回一个ID,因此它在插入的末尾附加一个select-scope_identity()。

现在,对于可更新视图,scope_identity被破坏了,因为插入发生在另一个作用域中,并且返回null,所以插入失败。

如果从模型中删除此StoreGeneratedPattern=“Identity”,则实体框架不会附加select scope_Identity(),并且插入操作正常。

我希望这能解决你的问题,不要太迟。

干杯

此处提供更多详细信息:http://social.msdn.microsoft.com/Forums/en-US/adodotnetentityframework/thread/9fe80b08-0b67-4163-9cb0-41dee5115148/





相关问题
handling exceptions IN Action Filters

Is there a better way to handle exceptions that occur inside an Action Filter itself in ASP .NET MVC? There re 2 ways I can think of at the moment. Using a try catch and setting the HTTP Status ...

既可捕获,又可举出例外。

我有一种办法,可以进入亚洲开发银行,因此,我国的亚行在多瑙河航道中的所有 st子都位于一个试捕区。 它正在追捕Kexception

Cross compiler exception handling - Can it be done safely?

I am doing some maintenance on a C++ windows dll library that is required to work with different VC++ compilers (as I don’t want to address different mangling schemes). I have already eliminated any ...

File Handling Issue

I am developing a tool in c#, at one instance I start writing into a xml file continuously using my tool,when i suddenly restart my machine the particular xml file gets corrupted, what is the reason ...

Watch a memory location/install data breakpoint from code?

We have a memory overwrite problem. At some point, during the course of our program, a memory location is being overwritten and causing our program to crash. the problem happens only in release mode. ...

Unit Test for Exceptions Message

Is there a simple (Attribute-driven) way to have the following test fail on the message of the exception. [TestMethod()] [ExpectedException(typeof(ArgumentException))] public void ExceptionTestTest() ...

热门标签