简体   繁体   English

FluentNhibernate:查询以检索不同的值

[英]FluentNhibernate: Query to retrieve distinct values

Using FluentNhibernate 1.3.0.0, NHibernate 3.3.1.4000 on a DB2 LUW 9.7 database. 在DB2 LUW 9.7数据库上使用FluentNhibernate 1.3.0.0,NHibernate 3.3.1.4000。

I want to get some distinct data from only one table / entity. 我想从一个表/实体中获取一些不同的数据。 In SQL, it´s easy: 在SQL中,很简单:

select distinct Corporation, CalculationDate, ValuationRule
from MySchema.MyTable
where State == 0

Now, i´m trying to get those data using Linq, but it won´t work... 现在,我正在尝试使用Linq获取这些数据,但它无法正常工作......

First try using select: 首先尝试使用select:

var result = Session.Query<MyEntity>()
        .Where( x => x.State == State.Pending)
        .Select(
           x =>
              new
              {
                 Corporation = x.Corporation,
                 CalculationDate = x.CalculationDate,
                 ValuationRule = x.ValuationRule,
              }).Distinct().ToList();

Resulting exception: Expression type 'NhDistinctExpression' is not supported by this SelectClauseVisitor. 产生的异常:此SelectClauseVisitor不支持表达式类型'NhDistinctExpression'。

Second try, using Groupby and only getting the keys: 第二次尝试,使用Groupby并只获取密钥:

var result = Session.Query<MyEntity>()
        .Where( x => x.State == State.Pending)
        .GroupBy(
           x =>
              new
              {
                 Corporation = x.Corporation,
                 CalculationDate = x.CalculationDate,
                 ValuationRule = x.ValuationRule,
              }).Select( x => x.Key).ToList();

Resulting Exception: "Could not execute Query". 结果异常:“无法执行查询”。 Complaining about another field "Model" missing in the group by clause that is stated in the select term. 抱怨选择术语中所述的group by子句中缺少的另一个字段“Model”。 This is totally confusing me, as the specified field exists in the table but i dont want to use that field in that use case... 这让我很困惑,因为表中存在指定的字段,但我不想在该用例中使用该字段...

What is it i am missing? 我错过了什么?

Try to use QueryOver... 尝试使用QueryOver ...

var result = Session.QueryOver<MyEntity>()
    .Where(x => x.State == State.Pending)
    .SelectList(list => list
        .SelectGroup(x => x.Corporation)
        .SelectGroup(x => x.CalculationDate)
        .SelectGroup(x => x.ValuationRule)               
    )
    .ToList();

If you want to use distinct: 如果你想使用distinct:

var result = Session.QueryOver<MyEntity>()
    .Where(x => x.State == State.Pending)
    .SelectList(list => list
                .Select(Projections.Distinct(Projections.Property<MyEntity>(x => x.Corporation)))
                .Select(x => x.CalculationDate)
                .Select(x => x.ValuationRule)
                 )
                .ToList();

In both examples from Brenda are missing the transformation. 在布伦达的两个例子中都缺少转型。

Disclaimer: Check first if the types are correct in the DTO or in the Linq projection. 免责声明:首先检查DTO或Linq投影中的类型是否正确。

public class MyDto
{
    public string Corporation { get; set; }
    public DateTime? CalculationDate { get; set; }
    public string ValuationRule { get; set; }
}

MyDto myDto = null;

var result = Session.QueryOver<MyEntity>()
    .Where(x => x.State == State.Pending)
    .SelectList(list => list
        .Select(Projections.Distinct(Projections.Property<MyEntity>(x => x.Corporation))).WithAlias(() => myDto.Corporation)
        .Select(x => x.CalculationDate).WithAlias(() => myDto.CalculationDate)
        .Select(x => x.ValuationRule).WithAlias(() => myDto.ValuationRule)
        )
    .TransformUsing(Transformers.AliasToBean<MyDto>())
    //.TransformUsing(Transformers.AliasToBean<MyEntity>()) // You can use your entity but i recommend to use a DTO (Use MyEntity in the alias too)
    .ToList();

If you dont want to use a transformer, you need to cast to obj array: 如果你不想使用变换器,你需要转换为obj数组:

var result = Session.QueryOver<MyEntity>()
    .Where(x => x.State == State.Pending)
    .SelectList(list => list
        .Select(Projections.Distinct(Projections.Property<MyEntity>(x => x.Corporation)))
        .Select(x => x.CalculationDate)
        .Select(x => x.ValuationRule)
        )
    .ToList<object[]>()
    //.Select(x => new    // This is optional to use anonymus type instead a object[]
    //      {
    //         Corporation = (string) x[0],
    //         CalculationDate = (DateTime?) x[1],
    //         ValuationRule = (string) x[2]
    //      })
    //.List()
    ;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM