2009-08-21 3 views
6

SQL 관련 질문이 2 개 있습니다. 내 모델의 모습을 보려면 아래 이미지를 참조하십시오.자기 참조 테이블의 SQL 엔티티에 Linq를 열심히로드

질문 1

내가 내려고 얼마나 열망 내 User 클래스/테이블에 부하 User.AddedByUser 필드. 이 필드는 User.AddedByUserId 필드의 관계에서 생성됩니다. 이 테이블은 스스로 참조하고 있으며 Linq가 SQL에 User.AddedByUser 속성을 열심히로드하도록하는 방법을 알아 내려고 노력하고 있습니다. 즉, User 엔티티가로드되거나 페치 될 때마다 User.AddedByUser 및 User.ChangedByUser도 가져와야합니다. . 그러나, 나는이 재귀 문제가 될 수 있다는 것을 이해 ...

업데이트 1.1 :

var options = new DataLoadOptions(); 
options.LoadWith<User>(u => u.ChangedByUser); 
options.LoadWith<User>(u => u.AddedByUser); 

db = new ModelDataContext(connectionString); 
db.LoadOptions = options; 

을하지만 그렇지 않은 : 나는 다음과 같이 DataLoadOptions를 사용하려고했습니다

객체 그래프가 허용되지 않습니다 -

System.InvalidOperationException occurred 
    Message="Cycles not allowed in LoadOptions LoadWith type graph." 
    Source="System.Data.Linq" 
    StackTrace: 
     at System.Data.Linq.DataLoadOptions.ValidateTypeGraphAcyclic() 
     at System.Data.Linq.DataLoadOptions.Preload(MemberInfo association) 
     at System.Data.Linq.DataLoadOptions.LoadWith[T](Expression`1 expression) 
     at i3t.KpCosting.Service.Library.Repositories.UserRepository..ctor(String connectionString) in C:\Development\KP Costing\Trunk\Code\i3t.KpCosting.Service.Library\Repositories\UserRepository.cs:line 15 
    InnerException: 

이 예외는 매우 자명하다 : 일, 나는 2 호선에 다음과 같은 예외가 주기적이다. 또한 Line 2가 예외를 발생시키지 않는다고 가정하면 Line 3가 중복 키이므로 분명히 확신합니다.

업데이트 1.2 :

다음 중 하나 (업데이트 1.1 상기 연동 해에 사용되지 않음)이 작동하지 않는다 :

그것은 다음, 자명 한 예외를 발생
var query = from u in db.Users 
      select new User() 
      { 
       Id = u.Id, 
       // other fields removed for brevityy 
       AddedByUser = u.AddedByUser, 
       ChangedByUser = u.ChangedByUser, 

      }; 
return query.ToList(); 

:

System.NotSupportedException occurred 
Message="Explicit construction of entity type 'i3t.KpCosting.Shared.Model.User' in query is not allowed." 

이제 어떻게 해결할 수 있을까요? 도와주세요!

내 DB의 다른 모든 테이블에 질문 2

및 SQL 모델에 따라서 Linq에, 나는 두 개의 필드, Entity.ChangedByUser가와 Entity.AddedByUser (Entity.ChangedByUserId 외래 키/관계에 링크) (Entity.AddedByUserId 외래 키 연결을/관계)

Linq에서 SQL을 열어서이 필드를 날로드하려면 어떻게해야합니까? 내 쿼리에 대한 간단한 조인이 필요합니까? 아니면 다른 방법이 있습니까?

Linq to SQL eager loading on self referencing table http://img245.imageshack.us/img245/5631/linqtosql.jpg

답변

3

어쩌면 당신은 뒤로 물러서서 당신이 원하는 것을보고 시도 할 수 있습니다 을하면의 관계로 할 수 있습니까? 나는이 정보를 사용자에게 예를 들어 다음과 같이 표시하려고한다고 가정합니다. "Iain Galloway 님이 8 시간 전에 수정".

다음과 같은 작업을 할 수 있습니까? : -

var users = from u in db.Users 
      select new 
      { 
       /* other stuff... */ 
       AddedTimestamp = u.AddedTimestamp, 
       AddedDescription = u.AddedByUser.FullName, 
       ChangedTimestamp = u.ChangedTimestamp, 
       ChangedDescription = u.ChangedByUser.FullName 
      }; 

저는 (imo) 명료성을 위해 익명의 유형을 사용했습니다. 원하는 경우 사용자 유형에 해당 속성을 추가 할 수 있습니다.

두 번째 질문으로, 일반 LoadWith (x => x.AddedByUser) 등은 잘 작동해야합니다. 데이터베이스에 직접 설명 문자열을 저장하는 편이 낫지 만 - ChangedByUser.FullName이 변경 될 때 업데이트되는 내용과 ChangedByUser가 삭제 된 경우 (예 : DELETE CASCADE 또는 코드에서 null ChangedByUser를 처리하는 경우) 복잡하고 어긋난 경우가 있습니다.

+0

예 GUI에 해당 정보를 표시하고 싶습니다. 나는 익명의 타입을 사용하지 않고이 문제를 해결하기를 희망했다. 그러나 나는 그것이 문제를 해결하는 편도 방법이라고 생각한다. 내 문제는 많은 관계 많은 대처에 SQL의 무능력 Linq 관련이 있습니까? –

+0

Na를 사용하면 User.AddedDescription 및 User.ChangedDescription 필드를 User 클래스에 추가 할 수 있습니다. 그러면 anon 유형을 사용할 필요가 없습니다. 많은 관계 (실제로는 각 관계가 1 : 1)와 관련이 없습니다. SQL을 직접 작성하는 경우 AddedByUser의 모든 속성 (예 : AddedByUser 등)을 무한대로 가져 오지 않으려 고합니다. 당신은 아마도 자신의 이름을 붙잡을 것입니다. 그리고/또는 당신의 견해에 필요한 세부 사항을 잡을 것입니다. 이건 좀 더 일반적인 O/RM 문제입니다. 난 당신이 L2E 또는 최대 절전 모드와 동일한 문제가있을 것 같아요. –

0

는 확실하지 LINQ to SQL은이 문제에 대한 해결책이있다. Sql Server 2005를 사용하는 경우 일반적인 테이블 식을 사용하여 원하는 결과를 얻고 DataContext.ExecuteQuery를 사용하여 실행하는 Stored Procecdure를 (재귀 적으로) 정의 할 수 있습니다.

4

Any type of cycles just aren't allowed. LoadWith<T> 또는 AssociateWith<T>이 컨텍스트의 모든 유형에 적용되므로 무한 루프를 방지하는 내부 방법이 없습니다. 좀 더 정확히 말하자면, SQL Server가 CONNECT BYCTEs을 가지지 않아서 SQL을 생성하는 방법에 혼란 스러울뿐입니다. 실제로 Linq가 제공된 프레임 워크로 자동 생성 할 수있는 것보다 깁니다.

가장 좋은 방법은 수동으로 어린이와 익명 유형 모두에 대해 사용자 테이블로 1 단계 조인을 수행하여 반환하는 것입니다. 죄송합니다 그것은 깨끗한/쉬운 해결책이 아니지만, Linq와 함께 지금까지 사용할 수있는 모든 것입니다.