让我们从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>();
此 QueryOver 将生成包含所有 EntityType 及其字段的 SQL 语句。现在我们必须提取唯一的 EntityType 实例并填充它们的字段列表
有一个 DTO 类的概述(以及上面的 QueryOver,这些只包含很少的属性作为示例):
public class EntityTypeDTO
{
public virtual int ID { get; set; }
public virtual string Title { get; set; }
public virtual IList<CustomFieldDTO> Fields { get; set; }
...
}
public class CustomFieldDTO
{
public virtual int ID { get; set; }
public virtual string Name { 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 是临时的,仅用于此目的......但这种方法可以扩展