装满子查询DTO的财产NHibernate的查询

问题描述:

我有一个DTO对象是这样的:装满子查询DTO的财产NHibernate的查询

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,名称和个性化......因为我的实体可以有30场或更多...

谢谢。

+0

所以没有'Entity.Children'属性? – 2013-04-10 18:38:18

+0

不,在我的'Entity'类中,我有Parent属性来引用另一个实体,(不需要相同的类型)。我只想知道是否有儿童引用有问题的实体。 – 2013-04-10 19:07:51

+0

我不太熟悉NHibernate,但不应该在linq中使用'Session.Query'吗? – 2013-04-10 19:10:30

使用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的这个工作的例子。我曾经刺过它,但不能得到它的工作..

+0

谢谢Rippo,但它可以帮助我,但我解决它使用LINQ查询''let'操作符,例如:var query = from d in Query let c = d。 Parents.Any()选择新的ViewModel(...)'。谢谢 – 2013-04-11 11:19:23

+0

完美,不知道ANY还没有实现。很高兴看到他们让LINQ提供商变得更好。 – Rippo 2013-04-11 11:48:38

+0

注意你有时候有实际的计数是有用的,但不是在所有情况下。 – Rippo 2013-04-11 11:49:25

难道你没有考虑使用其他方法而不是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); 
    } 
} 
+0

好吧,我不能再改变它了。你知道我该怎么做? – 2013-04-10 17:43:42

+0

已编辑答案与SQL查询和短小使用 – Dima 2013-04-11 03:35:19