Nhibernate 如何使用条件或QueryOver API编写此linq查询

Nhibernate 如何使用条件或QueryOver API编写此linq查询,nhibernate,transform,linq-to-nhibernate,criteria-api,queryover,Nhibernate,Transform,Linq To Nhibernate,Criteria Api,Queryover,是否可以将下面的代码转换为NHibernate中使用查询(linq)api编写的Criteria或QueryOver api?我用它来将数据格式化成DTO,而且它只需要一次到db的往返 注意:我尝试了transformers.aliastobean,但一次只能使用一个transformer。是否可以在一个查询中使用多个transformer from entityType in Provider.GetSession().Query<crmEntityType>()

是否可以将下面的代码转换为NHibernate中使用查询(linq)api编写的Criteria或QueryOver api?我用它来将数据格式化成DTO,而且它只需要一次到db的往返

注意:我尝试了transformers.aliastobean,但一次只能使用一个transformer。是否可以在一个查询中使用多个transformer

     from entityType in Provider.GetSession().Query<crmEntityType>()
     .Fetch(x => x.Association)
     .Fetch(x => x.Fields)
     .AsEnumerable()
     where instanceIDs.Contains(entityType.Instance.instanceID)
     select new EntityTypeDTO()
     {
     ID = entityType.ID,
     Title = entityType.Title,
     Association = entityType.Association.Distinct().Select(asc => asc.ID).ToArray<int>(),
     Fields = entityType.Fields.Distinct().Select(fi => new CustomFieldDTO { 
 ID = fi.ID,
 Name =  fi.Name,
 Value = fi.Value,
 EntityType = fi.EntityType.ID,
 Type = fi.Type 
}).ToList()
     }).ToList();
来自Provider.GetSession().Query()中的entityType
.Fetch(x=>x.Association)
.Fetch(x=>x.Fields)
.可计算的()
其中instanceID.Contains(entityType.Instance.instanceID)
选择新EntityTypeDTO()
{
ID=entityType.ID,
Title=entityType.Title,
Association=entityType.Association.Distinct(),
Fields=entityType.Fields.Distinct().Select(fi=>new CustomFieldDTO{
ID=fi.ID,
Name=fi.Name,
值=fi.值,
EntityType=fi.EntityType.ID,
Type=fi.Type
})托利斯先生()
}).ToList();

让我们从
QueryOver
语法开始:

// external filter data
instanceIDs = new int[] { 1, 2, 3 };

// aliasing
EntityTypeDTO entityDTO = null;
CustomFieldDTO fieldDTO = null;
Field field = null;

IQueryOver<EntityType, Field> query = Session.QueryOver<EntityType>()

  // filter Entity by ID's list
  .Where(Restrictions.On<EntityType>(c => c.ID).IsIn(instanceIDs))

  // Join Fields
  .JoinQueryOver<Field>(c => c.Fields, () => field)
  .SelectList(list => list

    // entity
    .Select(c => c.ID)
    .Select(c => c.Title)
    // ... more Entity properties

    // field collection
    .Select(() => field.ID)
    .Select(() => field.Name)
    // ... more Field properties
  )
  .TransformUsing(new MyTransformer()); // see below

var dtos = query.List<EntityTypeDTO>();
//外部筛选器数据
instanceId=newint[]{1,2,3};
//混叠
EntityTypeDTO entityDTO=null;
CustomFieldDTO-fieldDTO=null;
字段=空;
IQueryOver query=Session.QueryOver()
//按ID的列表筛选实体
.Where(限制.On(c=>c.ID).IsIn(实例ID))
//连接字段
.JoinQueryOver(c=>c.Fields,()=>field)
.SelectList(list=>list
//实体
.选择(c=>c.ID)
.选择(c=>c.Title)
//…更多实体属性
//野外采集
.选择(()=>field.ID)
.选择(()=>field.Name)
//…更多字段属性
)
.TransformUsing(新的MyTransformer());//见下文
var dtos=query.List();
此查询将生成包含所有EntityTypes及其字段的SQL语句。现在我们必须提取唯一的EntityType实例并填充它们的字段列表

这里概述了DTO类(以及上面的QueryOver,这些类仅包含几个属性作为示例):

公共类EntityTypeDTO
{
公共虚拟整数ID{get;set;}
公共虚拟字符串标题{get;set;}
公共虚拟IList字段{get;set;}
...
}
公共类CustomFieldDTO
{
公共虚拟整数ID{get;set;}
公共虚拟字符串名称{get;set;}
...
}
最后是诀窍MyTransformer()

public class MyTransformer : IResultTransformer
{
  // rows iterator
  public object TransformTuple(object[] tuple, string[] aliases)
  {
    var entity = new EntityTypeDTO
    {
      ID = (int)tuple[0],         // aliases should be used
      Title = tuple[1] as string  // first two are belong to Entity
    };
    var field = new CustomFieldDTO
    {
      ID = (int)tuple[2],         // last 2 columns are for a Field
      Name = tuple[3] as string   // see SelectList in QueryOver
    };
    entity.Fields = new List<CustomFieldDTO> { field };
    return entity;
  }

  // convert to DISTINCT list with populated Fields
  public System.Collections.IList TransformList(System.Collections.IList collection)
  {
    var results = new List<EntityTypeDTO>();
    foreach(var item in collection)
    {
      var entity = item as EntityTypeDTO;

      // was already the same ID appended
      var existing = results.SingleOrDefault(c => c.ID.Equals(entity.ID));
      if(existing != null)
      {
        // extend fields
        existing.Fields.Add(entity.Fields.First());
        continue;
      }

      // new ID found
      results.Add(entity);
    }
    // DISTINCT list of Entities, with populated FIELDS
    return results;
  }
  ...
公共类MyTransformer:IResultTransformer
{
//行迭代器
公共对象转换元组(对象[]元组,字符串[]别名)
{
var实体=新实体类型DTO
{
ID=(int)元组[0],//应使用别名
Title=元组[1]作为字符串//前两个属于实体
};
var字段=新的CustomFieldDTO
{
ID=(int)tuple[2],//最后两列用于字段
Name=元组[3]作为字符串//请参见QueryOver中的SelectList
};
entity.Fields=新列表{field};
返回实体;
}
//转换为具有填充字段的不同列表
public System.Collections.IList转换列表(System.Collections.IList collection)
{
var results=新列表();
foreach(集合中的var项)
{
var entity=作为EntityTypeDTO的项目;
//已经附加了相同的ID
var existing=results.SingleOrDefault(c=>c.ID.Equals(entity.ID));
if(现有!=null)
{
//扩展字段
现有的.Fields.Add(entity.Fields.First());
继续;
}
//找到新ID
结果:增加(实体);
}
//具有填充字段的实体的不同列表
返回结果;
}
...

MyTransformer是一个特别的工具,仅用于此目的……但这种方法可以扩展

您认为性能需要这样的实现,还是我用Linq语法编写的第一个查询就足够了?我使用的是Criteria API和QueryOver(没有NHibernate的Linq实现经验)。如果第一个/您的SQL适合您,并且不需要移动到标准…使用它。性能应该相同!生成的两个SQL应该相似。。。
public class MyTransformer : IResultTransformer
{
  // rows iterator
  public object TransformTuple(object[] tuple, string[] aliases)
  {
    var entity = new EntityTypeDTO
    {
      ID = (int)tuple[0],         // aliases should be used
      Title = tuple[1] as string  // first two are belong to Entity
    };
    var field = new CustomFieldDTO
    {
      ID = (int)tuple[2],         // last 2 columns are for a Field
      Name = tuple[3] as string   // see SelectList in QueryOver
    };
    entity.Fields = new List<CustomFieldDTO> { field };
    return entity;
  }

  // convert to DISTINCT list with populated Fields
  public System.Collections.IList TransformList(System.Collections.IList collection)
  {
    var results = new List<EntityTypeDTO>();
    foreach(var item in collection)
    {
      var entity = item as EntityTypeDTO;

      // was already the same ID appended
      var existing = results.SingleOrDefault(c => c.ID.Equals(entity.ID));
      if(existing != null)
      {
        // extend fields
        existing.Fields.Add(entity.Fields.First());
        continue;
      }

      // new ID found
      results.Add(entity);
    }
    // DISTINCT list of Entities, with populated FIELDS
    return results;
  }
  ...