如何使用NHibernate.SqlCommand.JoinType.RightOuterJoin?

时间:2012-10-26 08:00:35

标签: nhibernate nhibernate-criteria

我有项目和客户模型。 项目模型具有带有<many-to-one> mapping.in数据库的Customer对象,这可能是客户存在但项目表中没有条目的情况。

我正在使用CustomerSearch功能,用户可以在其中输入项目或客户名称。如果用户只输入customername,那么我想要所有与CustomerName匹配的记录,而不考虑客户是否有项目。

我在服务中试过这个。

ICriteria criteria = session.CreateCriteria(typeof(Project),"Project")
                    .CreateAlias("Project.customer","customer",NHibernate.SqlCommand.JoinType.RightOuterJoin)
                    .CreateAlias("Project.Coordinator", "Coordinator", NHibernate.SqlCommand.JoinType.InnerJoin);

                if (!string.IsNullOrEmpty(custName))
                {
                    criteria.Add(Expression.Like("customer.Name", custName, MatchMode.Start));
                }
                if (!string.IsNullOrEmpty(projectName))
                {
                    criteria.Add(Expression.Like("Project.Name", projectName, MatchMode.Start));
                }

                projectList = criteria.List<Project>().ToList();

我使用RightOuterJoin给客户,因为项目表可能没有客户记录,但客户表必须有这些记录。

如果我看到projectList它有列表但是项目表中没有记录的项目为空,则此代码也没有给出任何错误。

我怎样才能获得这样的记录?

1 个答案:

答案 0 :(得分:0)

使用右连接项目的所有字段都为null,因此NH无法构建有效的项目对象(id缺失),因此它返回null。

你必须将值投射到某个对象中,以便NH知道如何处理null项目或单独查询没有项目的客户(使用Futures不需要单独的往返)。

class SearchResult
{
    public int ProjectId { get; set; }
    public string ProjectName { get; set; }
    public int CustomerId { get; set; }
    public string CustomerName { get; set; }
}


ICriteria criteria = session.CreateCriteria(typeof(Project))
    .CreateAlias("Customer","customer", JoinType.RightOuterJoin)
    .CreateAlias("Coordinator", "Coordinator", NHibernate.SqlCommand.JoinType.InnerJoin);

if (!string.IsNullOrEmpty(custName))
{
    criteria.Add(Expression.Like("customer.Name", custName, MatchMode.Start));
}
if (!string.IsNullOrEmpty(projectName))
{
    criteria.Add(Expression.Like("Name", projectName, MatchMode.Start));
}

criteria.SetProjection(Projection.List()
    .Add(Projections.Property("Id"), "ProjectId")
    .Add(Projections.Property("Name"), "ProjectName")
    .Add(Projections.Property("customer.Id"), "CustomerId")
    .Add(Projections.Property("customer.Name"), "CustomerName"));

projectList = criteria
    .SetTransforer(Transformers.AliasToBean<SearchResult>())
    .List<Project>();