3

EF4에서 상위/하위 관계가있는 엔티티를 저장하려고하면 문제가 발생합니다. 때로는 자식이 부모 앞에서 삽입 될 것입니다. 이는 명백히 참조 제약 조건에서 문제를 일으킬 것입니다. 두 테이블은 다음과 같이 구성되어 있습니다.노출 된 외부 키없이 잘못된 순서로 저장된 엔티티

OrderHeader 
- OrderID (PK) 

OrderDetails 
- OrderID (PK) 
- DetailID (PK) 

(더 많은 열이 있지만 중요하지 않습니다.)

참고 : 우리는 OrderDetails.OrderID에 실제 외래 키를 노출하지 않지만 대신 트리거를 사용하여 Details 테이블의 OrderID가 Header 테이블에 존재하도록합니다. FK를 노출하는 것이 빠른 해결책 일 수 있지만 우리의 응용 프로그램에서는 데이터베이스에 대한 이러한 종류의 변경이 허용되지 않습니다. 기존 코드를 다루어야합니다.

.edmx 파일의 XML을 보면 디자이너가 생성 할 때마다 개념 모델 (CSDL 섹션)에서 AssociationSet 및 Association을 만들고 Association에 ReferentialConstraint가 설정되었음을 알았습니다. 그러나 SSDL 섹션에 AssociateSet 또는 Assocation을 만들지는 않습니다. FK가 데이터베이스에 노출 될 때 추가되는 것처럼 보입니다. AdventureWorks 또는 Northwind와 같이 데이터베이스에서 실제 FK를 테스트 한 다른 데이터베이스의 경우 데이터베이스에서 모델을 생성 할 때 EDMX에 SSDL의 Association 및 AssociationSet 섹션이 포함되어있는 것을 볼 수 있습니다.

EF는 우리가 모델 (CSDL)에 갖고있는 연관성을 무시하고 대신 테이블 이름으로 사전 순으로 삽입합니다 - OrderDetail이 OrderHeader보다 먼저 정렬하기 때문에이 경우 운이 좋지 않습니다 (물론, 우리의 경우에는 테이블의 이름을 바꿀 권한이 있습니다). SSDL 섹션에 해당 AssociationSet 및 연관을 수동으로 추가하면 올바른 순서로 저장이 수행됩니다 (먼저 헤더를 삽입 한 다음 세부 정보 삽입). 그러나 '데이터베이스에서 모델 업데이트'를 수행 할 때마다 이러한 수동 변경 사항이 사라져 실제적인 해결책이 아닙니다. 나는 런타임에 역동적으로 수정 작업을하려고 노력했지만 그저 효과가 있어야 할 일을 해결하기위한 많은 노력이 필요하다고 생각했습니다.

EF가 삽입물을 주문할 때 CSDL에 정의 된 참조 제한 및/또는 연관을 존중할 수있는 방법이 있기를 바랍니다.

+0

재현 가능한 샘플이 있습니까? 나는 이것을 여러 번했고 간단하게 작동했습니다 (EFv4에서). –

+0

FK없이 작동 했습니까? 그것은 나를 위해 매번 깨어납니다. 동료가 EF 포럼에 대한 자세한 내용을 게시했습니다. 여기서 재현 가능한 사례를 볼 수 있습니다 : http://social.msdn.microsoft.com/Forums/en-US/adodotnetentityframework/thread/31ffcfa0-e69e-460b-a767-d28376a57fe9 큰 일은 어소시에이션이없는 것 같습니다. SSDL 섹션의 AssociationSet. 그것이 당신을 위해 일할 때, SSDL 섹션에 Association이 있습니까? –

+0

물론 .... 특별한 트리거가 없거나 SQL을 프로파일 링하지 않으면 '잘못된'동작을 놓치기 쉽습니다. FK가 없으면 SQL Server에서 머리글 앞에 Detail을 삽입 할 수 있지만 잘못된 동작입니다. –

답변

2

Ladislav Mrnkka의 대답을 듣고 '쉬운'해결책을 찾은 행운이없는 대신 대체 솔루션을 찾았습니다. 약간의 노력이 있었지만 최종 결과는 제 의견으로는 가치가 있습니다.

IModelTransofmrationExtension.OnBeforeModelSaved() 메서드를 사용하는 Visual Studio Extension을 만들었습니다. 이 방법에서는 EDMX 문서를 XDocument으로 지정하고 저장하기 전에 원하는대로 조작 할 수 있습니다. 이 기회를 통해 CSDL 섹션에서 SSDL에없는 연관 체 및 연관 체 세트를 검색합니다. 그런 다음 MSL 섹션의 데이터가있는 테이블/열 이름에 엔터티/속성 이름을 매핑 한 후 SSDL 섹션에 복사합니다.

이것은 효과적으로 우리의 협회에 실제 외래 키가 있다고 생각하게하여 EF가 올바른 순서로 INSERT를 수행하도록합니다.

유일한 단점은 우리 팀의 모델을 편집하는 모든 사용자가 확장 프로그램을 설치해야한다는 것입니다. 그렇지 않으면 생성 된 FK 연관을 얻지 못할 것입니다. 다행히도 우리는이 모델을 편집 할 수있는 사람들이 몇 명있어서 관리가 가능합니다.

+0

위대한 솔루션입니다. – Alireza

1

FK를 실제로 사용하기 위해 변경하는 것은 사용자가 원하는 것을 원하는대로 수행 할 수 있는지 확실하지 않습니다. 혹시 저장된 전체 proc을 두번째 insert를위한 id라면, 올바른 순서로 출력 절을 사용하여 id를 얻으려고 시도했다. proc를 호출하는 EF를 가지고 있는가?

+0

우리는 수동으로 (저장 프로 시저 또는 SaveChanges에 대한 여러 호출을 통해) 삽입 순서를 결정할 생각이었습니다. 그러나 우리는 이와 같이 많은 테이블을 보유하고 있습니다 - 일부는 더 복잡한 관계 (부모> 자식> 그랜드 자식) 등으로 인해 정말 그것을 피하려고합니다. –

3

지금은 문제를 이해하고 있다고 생각합니다. SSDL에는 전혀 관계가 없습니다. EF는 SQL 명령을 생성 할 때 SSDL의 정보 만 사용하므로 CSDL에 정의 된 엔터티 간의 종속성을 알지 못합니다. 나중에 확인 하겠지만 EF 아키텍처의 버그/디자인 결함처럼 보입니다.

버그를 방지하려면 어떻게해야합니까? SSDL에서 연관 집합을 수동으로 정의하고 일부는 better tool (상업용)을 사용하여 EF 디자이너 및 업데이트 매핑을 사용하거나 디자이너가 단순한 시나리오에만 사용되므로 EDMX 수동 유지 관리로 이동하십시오.

또한이 문제는 MS Connect에 버그로보고하거나 Microsoft와의 파트너 관계가있는 경우 지원 티켓으로 제출할 수도 있지만 솔루션을 얻더라도 몇 개월이 걸릴 수 있습니다.

+0

정보를 제공해 주셔서 감사합니다. 그것은 제가 두려워했던 것을 확인시켜줍니다 - 우리는 EF가 이것을 고려하기 위해 SSDL에 협회가 필요합니다. 나는 그 도구를 보았는데 유망한 것처럼 보이지만 여전히 노력을 기울여야합니다. 이를 위해 내 자신의 Visual Studio Add-in을 만드는 방법을 살펴 보겠습니다. 우리는 그것이 어떻게되는지 보게 될 것입니다. 추가 정보가 있으면 도움이 될 것입니다. –

+1

심지어 EF6도 똑같습니다 ... 오작동 : ( –

관련 문제