3

基本上,我一直在努力做到這一點(基於兩列數不同):NHibernate的數不同(基於多列)

select count(distinct(checksum(TableA.PropertyA, TableB.PropertyB))) 
from TableA 
left outer join TableB 
on TableA.TableBId = TableB.Id 
where PropertyA like '%123%' 

被谷歌搜索上如何做到這一點,但沒有運氣。試過這個,但從來沒有真正的工作。這並不明顯基於這兩個屬性從兩個表計數:

var queryOver = c.QueryOver<TableA>(); 
TableB tableBAlias = null; 
TableA tableAAlias = null; 
ProjectionList projections = Projections.ProjectionList(); 

queryOver.AndRestrictionOn(x => x.PropertyA).IsLike("%123%"); 
projections.Add(Projections.CountDistinct(() => tableAAlias.PropertyA)); 

queryOver.JoinAlias(x => x.TableB ,() => tableBAlias, JoinType.LeftOuterJoin); 
projections.Add(Projections.CountDistinct(() => tableBAlias.PropertyB)); 

queryOver.Select(projections); 
queryOver.UnderlyingCriteria.SetProjection(projections); 
return queryOver.TransformUsing(Transformers.DistinctRootEntity).RowCount(); 

回答

5

好吧,這是要採取幾個步驟,所以多多包涵。我在這裏假設SQL服務器,但該說明應爲支持checksum 任何方言的工作:

  1. 創建支持checksum功能的自定義方言:

    public class MyCustomDialect : MsSql2008Dialect 
    { 
        public MyCustomDialect() 
        { 
         RegisterFunction("checksum", new SQLFunctionTemplate(NHibernateUtil.Int32, "checksum(?1, ?2)")); 
        } 
    } 
    
  2. 更新您的配置使用自定義方言(您可以在配置XML文件或代碼中執行此操作,有關更多信息,請參閱this answer)。以下是我做到了我的現有配置代碼中:

    configuration 
        .Configure(@"hibernate.cfg.xml") 
        .DataBaseIntegration(
         db => db.Dialect<MyCustomDialect>()); 
    
  3. 創建調用checksum自定義投影。這一步是optional--你可以調用Projections.SqlFunction直接,如果你想,但我認爲它重構到一個單獨的功能是清潔:

    public static class MyProjections 
    { 
        public static IProjection Checksum(params IProjection[] projections) 
        { 
         return Projections.SqlFunction("checksum", NHibernateUtil.Int32, projections); 
        } 
    } 
    
  4. 撰寫您QueryOver查詢和調用自定義投影:

    int count = session.QueryOver<TableA>(() => tableAAlias) 
        .Where(p => p.PropertyA.IsLike("%123%")) 
        .Left.JoinQueryOver(p => p.TableB,() => tableBAlias) 
        .Select(
         Projections.Count(
          Projections.Distinct(
          MyProjections.Checksum(
           Projections.Property(() => tableAAlias.PropertyA), 
           Projections.Property(() => tableBAlias.PropertyB))))) 
        .SingleOrDefault<int>(); 
    

    這應該生成SQL,看起來像你以後:

    SELECT count(distinct checksum(this_.PropertyA, tableba1_.PropertyB)) as y0_ 
    FROM [TableA] this_ 
        left outer join [TableB] tableba1_ 
        on this_.TableBId = tableba1_.Id 
    WHERE this_.PropertyA like '%123%' /* @p0 */ 
    


仍在試圖找出是否有映射函數的方式,而無需手動指定的參數個數

+0

RegisterFunction(「校驗」,新SQLFunctionTemplate(NHibernateUtil.Int32,「校驗(?1,?2 )「))這個主題很棒! –

+0

@ eaon21:很高興幫助! –