我有一个使用nhibernate和linq的应用程序来对数据库进行查询。一切正常但我有跟随模型映射(与自动相关):
public class A
{
public virtual int Id { get; set; }
public virtual A ParentA { get; set; }
}
我有一个方法来处理一些信息,这个方法采用count
整数参数。
我想知道是否有任何方法可以访问ParentA属性的count
次以创建过滤器。
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 Expression?
答案 0 :(得分: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);
}
答案 1 :(得分: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; }
}