4

我有一个使用 nhibernate 和 linq 对数据库进行查询的应用程序。一切正常,但我映射了以下模型(与自动相关):

public class A
{
    public virtual int Id { get; set; } 
    public virtual A ParentA { get; set; }  
}

我有一个方法来处理一些信息,这个方法采用一个count整数参数。我想知道是否有任何方法可以访问countParentA 属性创建过滤器的时间。

protected void Proccess(int count, int id)
{
    var query = session.Query<A>();

    // I would like to access, the number of count variable in parentA property, something like:
    // for sample: if count is 3, I would like a query like: 
    query.Where(x => x.ParentA.ParentA.ParentA.Id == id);

    // maybe something like this:
    for (int i = 0; i < count; i++)
    {
        query.Where(x => x.ParentA.ParentA.ParentA.Id == id);   
    }

    var result = query.ToList();

    // continue method...
}

有没有办法创建这种 Lambda 表达式?

4

2 回答 2

2

像这样的东西应该工作:

protected void Process(int count, int id)
{
    var query = session.Query<A>().Where(BuildFilter(count,id));
    var result = query.ToList();
}

private static Expression<Func<A, bool>> BuildFilter(int count, int id)
{
   var x = Expression.Parameter(typeof(A), "x");

   Expression instance = x;
   if (count != 0)
   {
      var prop = typeof(A).GetProperty("ParentA");
      while (count > 0)
      {
         instance = Expression.Property(instance, prop);
         count--;
      }
   }

   var instanceId = Expression.Property(instance, "Id");
   var compareId = Expression.Constant(id);
   var body = Expression.Equal(instanceId, compareId);

   return Expression.Lambda<Func<A, bool>>(body, x);
}
于 2013-06-04T18:24:57.183 回答
1

生成的 SQL 不会像 Richard Deeming 的回答那样“好”,但这有利于那些不知道System.Linq.Expression命名空间的人阅读。

protected List<A> Proccess(int count, int id)
{
    var query = session.Query<A>()
              .Select(x => new Pair { Item = x, Ancestor = x };  
    Func<IQueryable<Pair>, IQueryable<Pair>> addNesting 
              = q.Select(x => new Pair{ Item = x.Item, Ancestor = Ancestor.Parent });
    foreach(var i in Enumerable.Range(0, count))
    {
        query = addNesting(query);
    }


    return query.Where(x => x.Ancestor == id).Select(x => x.Item).ToList();
}

private class Pair
{
   public A Item {get;set;}
   public A Ancestor { get; set; }
}
于 2013-06-04T18:34:57.653 回答