2011-02-11 2 views
1

ADO.NET Entity Framework 4에서 SQL Server에서 트리거 대신 "대신"을 사용하는 뷰에 레코드를 삽입 할 때 잘못된 연산 예외가 발생합니다. 오류 메시지가 표시됩니다.트리거가있는 뷰에 삽입 할 때 EF4 : ObjectContext가 일치하지 않습니다.

은 { "데이터베이스에 대한 변경 사항이 성공적으로 노력했지만, 개체 컨텍스트를 업데이트하는 동안 오류가 발생 된 ObjectContext가 일관성없는 상태에있을 수 있습니다 내부 예외 메시지 :.. EntityKey를 정의하는 키 - 값 쌍을 수 없습니다 null 또는 공백이됩니다. 매개 변수 이름 : 레코드 "}

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

이 간단한 예제에서는 연락처와 고용주라는 두 개의 테이블과 한 번에이 두 테이블에 행을 삽입하거나 가져올 수있는 Contacts_x_Employers 뷰를 만들었습니다. 표는 단지 ​​이름과 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 

닷넷 코드는 다음과 같습니다

을 using (var Context = new TriggersTestEntities()) { Contacts_x_Employers CE1 = 새 Contacts_x_Employers(); CE1.ContactName = "J"; CE1.EmployerName = "T"; Contacts_x_Employers CE2 = 새로운 Contacts_x_Employers(); CE1.ContactName = "W"; CE1.EmployerName = "C"; Context.Contacts_x_Employers.AddObject (CE1); Context.Contacts_x_Employers.AddObject (CE2); Context.SaveChanges(); // 오류 }에 맞춰

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> 

비주얼 스튜디오 솔루션 전체 응용 프로그램을 다시 만들 수있는 SQL 스크립트에서 찾을 수 있습니다 TestViewTrggers.zip은 ftp://JulioSantos.com/files/TriggerBug/입니다. 제공되는 모든 도움에 감사드립니다. 이미이 문제를 해결하기 위해 며칠을 보냈습니다.

답변

1

"대신 삽입"및 "대신 업데이트"트리거가있는보기에 행을 삽입하려고 할 때 동일한 문제가 발생했습니다.

Visual Studio의 마법사가 모델에서 뷰를 삭제하면 StoreGeneratedPattern = "Identity"가 일부 속성 (엔티티의 키)에 추가됩니다.

일반 테이블에서 요청을 생성 할 때이 속성은 엔티티 프레임 워크에 ID를 반환하도록 지시하므로 삽입 끝 부분에 select scope_identity()가 추가됩니다.

이제 업데이트 가능보기에서 삽입이 다른 범위에서 발생하고 null을 반환하므로 삽입이 실패하므로 scope_identity가 엉망입니다.

모델에서이 StoreGeneratedPattern = "Identity"를 제거하면 엔티티 프레임 워크에서 select scope_identity()가 추가되지 않고 삽입이 올바르게 작동합니다.

나는 이것이 당신의 문제를 해결하고 너무 늦지 않았 으면 좋겠다.

건배 여기

자세한 내용 : http://social.msdn.microsoft.com/Forums/en-US/adodotnetentityframework/thread/9fe80b08-0b67-4163-9cb0-41dee5115148/

+0

안녕 magicnico, 나는 정말 당신의 응답을 평가. 우리는 앞으로 나아갈 필요가 있기 때문에 조만간 시도 할 수 없으며 대신 RIA Services를 사용하여 테이블을 다시 형상화하기로 결정했습니다. 따라서 뷰를 사용하여 테이블을 가장하는 동일한 게임을 계속 수행하지만보기에 대한 업데이트 요청을 차단하고 작은 부분 (참여 테이블)에서이를 분해합니다. –

+0

그러나 회신이 끝날 때 Microsoft의 포럼 링크에서 귀하가 참조하는 "행 개수"부분을 발견 했으므로 귀하가 올바른 길에 있다는 것을 알고 있습니다. 응답 시간을내어 주셔서 감사합니다. 나는 당신의 대답을 구할 것이고, 나는 자유 시간을 얻 자마자 다른 시험을 치고 결과를 여기에 게시 할 것이다. 친애하는, –

관련 문제