2011-05-11 10 views
6

Bu senaryo var ayrı:NHibernate QueryOver

class User 
{ 
Id, 
UserName 
} 

class UserRelationship 
{ 
User GroupUser, 
User MemberUser 
} 

and query 

var query = QueryOver.Of<UserRelationship>() 
.JoinqueryOver(x=>x.MemberUser) 
.Where(x=>x.UserName == "TestUser"); 

Şimdi Liste Farklı Kullanıcı dönmek istiyorum, bu yüzden

TransformUsing (Transformers.DistinctRootEntity)

yapamaz Bu bana UserRelationship verecek.

public class User 
{ 
    public virtual int Id {get; set;} 
    public virtual string UserName {get; set;} 
} 

public class UserRelationship 
{ 
    public virtual int Id {get; set;} 
    public virtual User GroupUser {get; set;} 
    public virtual User MemberUser {get; set;} 
} 

Ve akıcı eşleştirmeleri:

public class UserMap : ClassMap<User> 
{ 
    public UserMap() 
    { 
     Id(x=>x.Id).GeneratedBy.Native(); 
     Map(x=>x.UserName); 
    } 
} 

public class UserRelationshipMap : ClassMap<UserRelationship> 
{ 
    public UserRelationshipMap(){ 
     Id(x=>x.Id).GeneratedBy.Native(); 
     References(x=>x.GroupUser); 
     References(x=>x.MemberUser); 
    } 
} 
Select distinct user.ID 
from UserRelationship relationship 
inner join User user on user.ID = relationship.MemberUser_ID 

sınıflar Verilen sayesinde

cevap

3

yardım edin:

Böyle bir şey gerek 10 UserRelationship sınıfından "MemberUser" temelli ayrı bir "Kullanıcı" listesi almak istiyorsunuz.

var distinctMemberUsers = QueryOver.Of<UserRelationship>() 
    .Select(x => x.MemberUser.Id); 

var users = QueryOver.Of<User>() 
    .WithSubquery.WhereProperty(x=>x.Id).In(distinctMemberUsers) 

Bu, SQL'de Kullanıcı'nın farklı bir listesini vermek için bir In yan tümcesi kullanmalıdır.

1

Bu yazının eski olduğunu biliyorum ama aynı sorunla karşılaştım ve daha basit olduğunu düşündüğüm bir cevabı paylaşacağımı düşündüm.

Ne olursa olsun - NHibernate her bir üst nesne için birden çok satır sorgulamalıdır (Birleşim yerine SubSelect kullanmıyorsanız). Bu nedenle, gerçekten sadece 100 benzersiz nesne olduğunda, 500 nesnenin bir listesini alacağımızı biliyoruz.

Bu nesneler zaten sorgulandığından ve zaten bellekte olduğundan - neden LINQ kullanmıyorsunuz?

Bu soruya dayanarak: LINQ's Distinct() on a particular property en + 'larla verilen cevap çok elverişli bir çözüm sunuyor. Başka bir liste oluşturun ve LINQ'un farklı karşılaştırmaları yapın. Veritabanında ayrı olarak yapabilseydik, bu daha iyi bir seçenek olurdu - ama bu bir seçenek değil, çünkü LINQ iyi bir çözüm gibi görünüyor.