在NHibernate Query中使用SubQuery填充DTO的属性

时间:2013-04-10 17:09:45

标签: c# linq nhibernate hql queryover

我有一个像这样的DTO对象:

public class TreeViewDTO
{
   public string Value { get; set; }
   public string Text { get; set; }
   public bool HasChildren { get; set; }
}

和我用Nhibernate映射的实体是:

public class Entity
{
   public virtual int Id { get; set; }
   public virtual string Name { get; set; }
   public virtual Entity Parent { get; set; }
   /* other properties */
}

我想知道,如何获取我的DTO列表并使用count方法或子查询填充HasChildren属性以了解是否有子项?

我试过这个,但是不起作用:

return Session.QueryOver<Entity>
                        .Select(entity => new TreeViewViewModel() {
                                                        Value = entity.Id.ToString(),
                                                        Text = entity.Name,
                                                        HasChildren = (Session.QueryOver<Entity>().Where(x => x.ParentId == entity.Id).RowCount() > 0)})
                        .ToList();

我得到了一个例外情况:NotSupportedException并且消息显示:x => (x.Parent.Id == [100001].Id)并且不支持。

如何创建查询以填充此属性?

PS:我想查询只选择Id,Name和Count ...因为我的实体可以有30个字段或更多...

谢谢。

2 个答案:

答案 0 :(得分:1)

你没有考虑过使用其他东西而不是NHibernate来完成这项工作吗? 在我看来,像Dapper这样的轻量级库可以成为这个用例的绝佳解决方案。你最终会得到一个简单的简单sql查询,而不是用Nhibernate摇晃。

修改
精巧的代码就像这样简单:

public IDbConnection ConnectionCreate()
{
    IDbConnection dbConnection = new SQLiteConnection("Data Source=:memory:;pooling = true;");
    dbConnection.Open();
    return dbConnection;
}

public void Select()
{
    using (IDbConnection dbConnection = ConnectionCreate())
    {
        var query = @"SELECT e1.id as Value, e1.name as Text, CASE WHEN EXISTS
                        (SELECT TOP 1 1 FROM Entity e2 WHERE e2.parent = e1.id) 
                        THEN 1 ELSE 0 END as HasChildren
                    FROM Entity e1";
        var productDto = dbConnection.Query<TreeViewDTO>(query);
    }
}

答案 1 :(得分:1)

使用NHibernate Linq提供程序,您可以这样做: -

public class dto
{
    public long Value { get; set; }
    public int Count { get; set; }
    public bool HasCount { get { return Count > 0; } }
}

注意:我的DTO有一个只读属性,用于查看实际计数,然后查询: -

var a = Db.Session.Query<Support>().Select(
         s => new dto {
                        Value = s.Id,
                        Count = s.CommentList.Count
                      }
            ).ToList();

这会生成以下sQL

select support0_.Id                                   as col_0_0_,
       (select cast(count(*) as SIGNED)
        from   supportcomment commentlis1_
        where  support0_.Id = commentlis1_.SupportId) as col_1_0_
from   support support0_

我从未见过使用QueryOver的相关工作示例。我曾经对它进行过刺杀但却无法正常工作..