2011-03-31 3 views
0

내 회사의 애플리케이션에서 일종의 "뉴스 피드"를 만들고 싶습니다. 시나리오에서 사용자 작업은 다른 종류의 "활동"을 생성하고 다른 사용자는 "뉴스 피드"에서 볼 수 있습니다.Fluent Nhibernate Lazy가 IList에서 Critist를로드합니까?

그러나 "활동"은 모든 사용자와 관련이 없으며 관계를 확인하기 위해 복잡한 코드가 있습니다.

여기 내 활동 클래스

나는 사용자가 볼 최신 10 개 뉴스를 할
public class Activity: IActivity 
{ 
    public virtual int Id { get; set; } 
    public virtual ActivityType Type { get; set; } 
    public virtual User User { get; set; } 
    public virtual bool IsVisibleToUser(User userLook) 
    { 
     // Complex business calculation etc. 
     return true; 
    } 
} 

입니다. 그러나 Activity 테이블이 상당히 커지고 성능이 문제가되기 때문에 이에 대한 모범 사례를하고 싶습니다.

내가 할 일은 마지막 활동 25 개를 얻고 사용자에게 표시 할 목록을 채우는 지 확인합니다. 예를 들어 사용자에게 5 개의 활동 만 표시되는 경우 25 개의 활동이 추가로 발생합니다.

내가 ID로 주문 전체 목록을 얻을 경우, 배우고, 그것을 사용자가 볼 경우 하나 하나를 검사 할
IList<Activity> resultList = session.CreateCriteria(typeof(Activity)) 
           .SetMaxResults(25) 
           .AddOrder(Order.Desc("Id")) 
           .List<Activity>(); 

는 것 NHibernate에 단지 내가 나를 위해 또는 사용하지 않는 개체를로드?

IList<Activity> resultList = session.CreateCriteria(typeof(Activity)) 
           .AddOrder(Order.Desc("Id")) 
           .List<Activity>(); 

int count = 0; 
foreach(Activity act in resultList){ 
    if (act.IsVisible(CurrentUser)){ 
     count++; 
     // Do something with act 
     if (count == 10) 
      break; 
    } 
} 

편집 : 여기 는 활동 모델 ActivityMapping된다. 귀하의 질문에 생성 된 SQL의 모습 방법에 대한 경우

public class ActivityMap : ClassMap<Activity> 
{ 
    public ActivityMap() 
    { 
     Id(x => x.Id); 
     Map(x => x.Type).CustomType(typeof(Int32)); 
     References(x => x.User).Nullable(); 
    } 
} 
+0

액티비티에 대한 Fluent NHibernate 매핑은 어떻게 정의되어 있습니까? – WorldIsRound

+0

질문이 업데이트되었습니다. 매핑은 간단합니다. – SadullahCeran

답변

3

, 내 생각은 다음과 같습니다 당신이 활동 횟수가 큰 것을 언급 한 이후

SELECT 
    this_.Id as Id0_0_, 
    this_.ActivityTypeas ActivityType_0_0_, 
    --Other fields 
FROM dbo.ActivityType this_ 
WHERE 
    --condition 
ORDER BY 
    --condition 

, 당신은 ICriteria 년대를 사용할 수있다 SetFirstResultSetMaxResult.

SetFirstResult(int)은 얻으려는 첫 번째 항목의 색인을 나타내며 SetMaxResult(int)은 얻고 자하는 행의 수를 나타냅니다 (귀하의 경우 25 개).

ToList은 메모리의 모든 레코드를 한 번에로드합니다.

[업데이트] 당신은 Enumerable에서()의 사용을하기 위해선, 기록 하나 하나를 반환 할 필요가있는 경우 -

당신이 당신의 쿼리 객체의 매우 큰 수를 반환 할 것으로 예상하지만 '돈 경우 이들 모두를 사용할 것으로 예상되면 System.Collections.IEnumerable을 반환하는 Enumerable() 메서드에서 성능이 향상 될 수 있습니다. 이터레이터는 초기 SQL 쿼리에서 반환 한 식별자를 사용하여 필요에 따라 개체를로드합니다 (n + 1은 전체 선택).

소스 - Link

+0

좋은 반응에 감사드립니다. 목록의 요소를 하나씩 메모리에로드 할 수 있습니까? Hibernate는 그 문제를 다루는 방법이나 설정을 가지고 있는가? – SadullahCeran

+0

빠른 응답 감사합니다. Enumerable은 내 경우에 매우 유용 할 것이다.그러나 Criteria API가 동일한 목적을 위해 Enumerable 메소드를 가지고 있다면 그것은 깔끔할 것입니다. – SadullahCeran

2

아니, 목록() 메소드는 한 번에 메모리에 모든 것을 가져옵니다.

+0

확인. 알았다. 내가 원하는 것을 성공할 수있는 대체 솔루션이 있는지 아십니까? – SadullahCeran