2009-05-19 3 views
7

나는 태그 기반 ASP.net 시스템을 작성 중이다.LINQ options.loadwith with problem

Topic <many-many> TagTopicMap <many-many> Tag

은 기본적으로는 3NF 접근 (toxi)이다 나는 다음에서 발견 : 다음 dB 방식 사용하여 코드를 여기에 http://www.pui.ch/phred/archives/2005/04/tags-database-schemas.html

이다 내가 가진 :

DataLoadOptions options = new DataLoadOptions(); 
     options.LoadWith<Topic>(t => t.TagTopicMaps); 
     options.LoadWith<TagTopicMap>(tt => tt.Tag); 
     var db = new lcDbDataContext(); 
     db.LoadOptions = options; 
     db.Log = w; 

     var x = from topic in db.Topics 
       orderby topic.dateAdded descending 
       select topic; 

     ViewData["TopicList"] = x.Take(10); 

이 스크립트를 실행하면 결과는 괜찮지 만 상위 10 개 항목의 목록을 가져 오는 11 개의 단일 SQL 쿼리가 제공됩니다.

SELECT TOP (10) [t0].[Id], [t0].[title], [t0].[dateAdded] 
FROM [dbo].[Topics] AS [t0] ORDER BY [t0].[dateAdded] DESC 
-- Context: SqlProvider(Sql2005) Model: AttributedMetaModel Build: 3.5.30729.1 

태그의 세부 정보를 개별적으로 얻는 데 사용되는 태그 중 10 개.

나는 켜거나 두 loadwith 문을 전환하려고 다음과 같은 일이 일어날 발견 : 예상대로 즉, 만 두 번째 loadwith 옵션이 작동

loadwith<topic> : no difference for on or off. 
loadwith<tagtopicmap>: 11 Queries when on, much more when off. 

. 첫 번째 효과는 없습니다!

또한 결과 집합 ToList()를 만들려고했습니다. 하지만 더 많은 문제가 발생합니다. 태그 세부 부분의 경우 해당 고유 항목 만 검색합니다. 모든 반복 태그 (동일한 태그가 여러 주제에 나타날 수 있습니다.)가 쿼리에 의해 삭제됩니다.

마지막 한가지, 나는 결과 tolist(), 난 (IList에)에 (된 IQueryable)을 변경 만드는 경우, 데이터를 검색하기 위해 영문으로 사용되는 코드입니다 :

<% foreach (var t in (IQueryable)ViewData["TopicList"]) 
     { 
      var topic = (Topic)t; 

    %> 
    <li> 
     <%=topic.title %> || 
     <% foreach (var tt in (topic.TagTopicMaps)) 
      { %> 
       <%=tt.Tag.Name%>, 
       <%} %> 
    </li> 
    <% 
     } 
    %> 

답변

5

짧은을 대답은 : LinqToSql 이런 식으로 몇 가지 단점이 있습니다. 그리고 때로는 당신은 work-arounds를 사용해야합니다 ...

Linq2Sql LoadWith 옵션은 단순히 데이터베이스 테이블 사이에 내부 조인을 일으키기 때문에 Linq 성명 (뭔가 오해를 용서해주세요, 나는 VB 구문에서 Linq를 writting하는 데 사용되는 ...) :

var x = from topic in db.Topics 
     join topicMap in topic.TagTopicMaps 
     orderby topic.dateAdded descending 
     group topicMap by topicMap.topic into tags = Group; 

이 구문은 잘못되었지만 Linq2Sql이 Topics와 TagTopicMaps 간의 조인을 평가 한 다음 그룹화 (또는 "그룹 조인", "let"등)를 사용하여 결과 집합에 객체 계층을 보존합니다.

+0

항상 INNER JOIN이 아닙니다. * 모든 조인 필드가 null 인 경우 * LEFT JOIN입니다. 조인 필드에 일부 (모두는 아니지만)가 포함될 수있는 경우에도 INNER JOIN이 생성하는 문서화되지 않은 "잘못된 기능"입니다. 열 *. –

1

datacontext 클래스의 EnabledDefferedLoad를 false로 설정하십시오.