Nhibernate count distinct (based on multiple columns)

后端 未结 1 980
野的像风
野的像风 2020-12-21 05:38

Basically, i have been trying to do this (count distinct based on two columns):

select count(distinct(checksum(TableA.PropertyA, TableB.PropertyB))) 
from Ta         


        
相关标签:
1条回答
  • 2020-12-21 06:06

    Okay this is going to take a few steps, so bear with me. I'm assuming SQL server here, but the instructions should work for any dialect that supports checksum1:

    1. Create a custom dialect that supports the checksum function:

      public class MyCustomDialect : MsSql2008Dialect
      {
          public MyCustomDialect()
          {
              RegisterFunction("checksum", new SQLFunctionTemplate(NHibernateUtil.Int32, "checksum(?1, ?2)"));
          }
      }
      
    2. Update your configuration to use the custom dialect (you can do this either in your configuration XML file or with code. See this answer for more information). Here's how I did it inside of my existing configuration code:

      configuration
          .Configure(@"hibernate.cfg.xml")
          .DataBaseIntegration(
              db => db.Dialect<MyCustomDialect>());
      
    3. Create a custom projection that calls checksum. This step is optional-- you can call Projections.SqlFunction directly if you'd like, but I think refactoring it into a separate function is cleaner:

      public static class MyProjections 
      {
          public static IProjection Checksum(params IProjection[] projections)
          {
              return Projections.SqlFunction("checksum", NHibernateUtil.Int32, projections);   
          }
      }
      
    4. Write your QueryOver query and call the custom projection:

      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>();
      

      This should generate SQL that looks like what you're after:

      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 */
      


    1Still trying to figure out if there's a way to map a function without manually specifying the number of arguments

    0 讨论(0)
提交回复
热议问题