功能NHibernate - ProjectionList - 的ICriteria将返回空值 [英] Fluent NHibernate - ProjectionList - ICriteria is returning null values

查看:134
本文介绍了功能NHibernate - ProjectionList - 的ICriteria将返回空值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在NHibernate的很新,但我周围的一派,也没有发现任何事情来帮助这个问题。我希望你们可以! ;)
我改变了属性的名称和方法,因为这个代码是公司的财产,但基本上这就是我需要一些帮助。

I'm quite new in NHibernate, but I have googled around and didn't found anything to help with this issue. I hope you guys can ! ;) I'm changing names of properties, and methods, because this code is company's property but basically this is what I need some help.

我有以下情形:

我的域实体:

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
}



我的地图类:

My map class:

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



存储库:

Repository:

    public IEnumerable<T> SelectByColumns()
    {
        ICriteria searchCriteria = _sessao.CreateCriteria<T>("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<T>());

        return searchCriteria.List<T>();
    }



最后通话:

And finally the call:

public IEnumerable<Person> GetManager()
{
    using (IDbSession dbSession = _sessionFactory.Create())
    {
        try
        {
            IRepository<Structure> _repository = dbSession.CreateRepository<Structure>();
            IEnumerable<Structure> 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查询象下面这样:

This generates me a sql query like below:

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

这是正是我需要的。如果我在Management Studio运行此查询,我得到了所有我所期待的结果。

And this is exactly what I need. If I run this query in management studio, I got all the results I was expecting.

但是,当我到达VAR managerList的structureList有所有的记录从SQL返回,但所有空值,如下所示:

But when I reach the var managerList, the structureList have all records returned from sql, but all with null values as shown:

我已经与CreateAlias​​ tryed,个createCriteria,返回的IList<>,返回IEnumerable的。
我已经改变Transformers.Alias​​ToBean()来Transformers.Alias​​ToEntityMap。
,很多不同的东西,我发现google搜索,但我总是得到相同的结果。

I have already tryed with CreateAlias, CreateCriteria, return IList<>, return IEnumerable. I've already changed Transformers.AliasToBean() to Transformers.AliasToEntityMap. A lot of different things I found googling, but I always got the same result.

我感谢所有帮助,感谢您的时间!

I appreciate any help, and thank you for your time!

推荐答案

您几乎没有。我们需要的,是正确地预测转化为实体/对象树。这需要两个步骤:

You are almost there. What we need, is to properly convert Projections into entity/object tree. That would require two steps:

我。使用别名为每列

列别名,是非常有用的多为事后处理,比SQL语句生成。但它是对下一步骤是必须的。因此,而不是这样的:

Column Alias, is useful more for ex post processing, than for SQL statement generation. But it is a must for next step. So instead of this:

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)的实体。在联合参考树的(多到一)的它不会起作用。但

In fact, this would be enough, if we are using the first level (no JOIN) entity. For JOINed reference tree (many-to-one) it won't work. but

二,使用自定义导致变压器

II. use custom result transformer

像往常一样,NHibernate的提供了许多开放点自定义扩展他们中的一个将是自定义IResultTransformer之一,准备处理的参考树,我们需要的是在这里:

As always, NHibernate provides many open points for custom extensions. One of them would be the Custom IResultTransformer. The one, ready to handle reference tree we need is here:

  • DeepTransformer

有,在我们的解决方案,我们应该不是这样的:

Having that in our solution we should instead of this:

searchCriteria.SetResultTransformer(Transformers.AliasToBean<T>());

使用这样的:

searchCriteria.SetResultTransformer(new DeepTransformer<T>());

这实行强烈地依赖于正确的别名设定,描述了真正的实体属性(使用反射来找到如何设置)。所以第一点 - 列/属性别名是真的必不可少的。

This implemenation is strongly dependent on proper alias setting, describing the real entity properties (to use reflection to find what to set). So the first point - column/property alias is really essential

这篇关于功能NHibernate - ProjectionList - 的ICriteria将返回空值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆