流畅的NHibernate – ProjectionList – ICriteria返回空值

我是NHibernate的新手,但我已经google了一下,并没有找到任何帮助解决这个问题。 我希望你们能! ;)我正在更改属性和方法的名称,因为此代码是公司的属性,但基本上这是我需要一些帮助。

我有以下情况:

我的域名实体:

public class Structure { public virtual int Id { get; set; } public virtual string Name { get; set; } public virtual Person Manager { get; set; } //I need to fill here. //and others } 

我的地图类:

 public class MapStructure : ClassMap { public MapStructure() { Table("TB_Structure"); Id(x => x.Id).Column("Id").GeneratedBy.Identity(); Map(x => x.Name).Column("Name"); References(x => x.Manager).Column("PersonId").Fetch.Join().NotFound.Ignore(); //... } } 

库:

  public IEnumerable SelectByColumns() { ICriteria searchCriteria = _sessao.CreateCriteria("this"); searchCriteria.CreateAlias("this.Manager", "Manager"); //Only for example purpose. Those columns come as an array string parameter, but the treatment is the same one. var columns = Projections.ProjectionList(); columns.Add(Projections.Property("Manager.Id")); columns.Add(Projections.Property("Manager.Name")); columns.Add(Projections.Property("Manager.Document")); searchCriteria.SetProjection(columns); searchCriteria.SetResultTransformer(Transformers.AliasToBean()); return searchCriteria.List(); } 

最后是电话:

 public IEnumerable GetManager() { using (IDbSession dbSession = _sessionFactory.Create()) { try { IRepository _repository = dbSession.CreateRepository(); IEnumerable structureList = _repository.SelectByColumns(); var managerList = (from structure in structureList where structure.Manager != null select new Person() { Id = structure.Manager.Id, Name = structure.Manager.Name, Document = structure.Manager.Document }); return managerList.OrderBy(x => x.Name); } catch (Exception) { throw; } } } 

这会生成一个如下所示的SQL查询:

 SELECT manager1_.PersonId as y0_, manager1_.Name as y1_, manager1_.Document as y2_ FROM TB_Structure this_ inner join TB_Person manager1_ on this_.ManagerId=manager1_.PersonId 

而这正是我所需要的。 如果我在管理工作室运行此查询,我得到了我期待的所有结果。

结果

但是当我到达var managerList时,structureList具有从sql返回的所有记录,但是所有记录都具有空值,如下所示:

运行sql查询后

我已经尝试过CreateAlias,CreateCriteria,返回IList ,返回IEnumerable。 我已经将Transformers.AliasToBean()更改为Transformers.AliasToEntityMap。 很多不同的东西,我发现谷歌搜索,但我总是得到相同的结果。

我感谢任何帮助,谢谢你的时间!

你快到了。 我们需要的是将投影正确地转换为实体/对象树。 这需要两个步骤:

I.使用每列的别名

列别名对于事后处理比对SQL语句生成更有用。 但这是下一步的必要条件。 所以不是这样的:

 columns.Add(Projections.Property("Manager.Id")); columns.Add(Projections.Property("Manager.Name")); columns.Add(Projections.Property("Manager.Document")); 

我们需要这个:

 columns.Add(Projections.Property("Manager.Id").As("Manager.Id"); columns.Add(Projections.Property("Manager.Name").As("Manager.Name")); columns.Add(Projections.Property("Manager.Document").As("Manager.Document")); 

实际上,如果我们使用第一级(无JOIN)实体,这就足够了。 对于JOINed参考树(多对一) ,它将无法工作。 但

II。 使用自定义结果变换器

与往常一样,NHibernate为自定义扩展提供了许多开放点。 其中一个是Custom IResultTransformer。 准备好处理我们需要的参考树的那个是:

  • DeepTransformer

在我们的解决方案中,我们应该代替这个:

 searchCriteria.SetResultTransformer(Transformers.AliasToBean()); 

用这个:

 searchCriteria.SetResultTransformer(new DeepTransformer()); 

此实现强烈依赖于正确的别名设置,描述真实的实体属性(使用reflection来查找要设置的内容)。 所以第一点 – 列/属性别名非常重要