C# 如何生成查询具有列表的对象的表达式树<;T>;作为财产?
请原谅我笨拙的解释,但我有一个包含列表的类:C# 如何生成查询具有列表的对象的表达式树<;T>;作为财产?,c#,linq-to-objects,expression-trees,C#,Linq To Objects,Expression Trees,请原谅我笨拙的解释,但我有一个包含列表的类: public class Document { public int OwnerId { get; set; } public List<User> Users { get; set; } public Document() { } } public class User { public string UserName { get; se
public class Document
{
public int OwnerId { get; set; }
public List<User> Users { get; set; }
public Document() { }
}
public class User
{
public string UserName { get; set; }
public string Department { get; set; }
}
有没有更有效的方法?如何使用泛型创建谓词-user=>user.Department-的表达式?听起来像是您想要的?我想出了一个比较满意的解决方案,可以使用如下语法执行查询:
var predicate = PredicateBuilder.True<Document>();
predicate = predicate.And<Document>(User.SubQuery("UserName", "DAVER"));
predicate = predicate.And<Document>(AdHoc<Document>("OwnerId", 1));
var finDocs = docs.AsQueryable().Where(predicate).ToList();
var predicate=PredicateBuilder.True();
谓词=谓词和(User.SubQuery(“UserName”、“DAVER”);
谓词=谓词和(即席(“所有者ID”,1));
var finDocs=docs.AsQueryable().Where(谓词).ToList();
我有一个使用此方法的扩展类:
public static Expression<Func<T, bool>> AdHoc<T>
(string columnName, object compValue)
{
// Determine type of parameter
ParameterExpression parameter = Expression.Parameter(typeof(T), "x");
// Target to compare to
Expression property = Expression.Property(parameter, columnName);
// The value to match
Expression constant = Expression.Constant(compValue, compValue.GetType());
Expression equality = Expression.Equal(property, constant);
Expression<Func<T, bool>> predicate =
Expression.Lambda<Func<T, bool>>(equality, parameter);
return predicate;
}
publicstaticexpressionadhoc
(字符串columnName,对象compValue)
{
//确定参数的类型
ParameterExpression参数=表达式参数(类型为(T),“x”);
//比较对象
Expression property=Expression.property(参数、列名);
//要匹配的值
表达式常量=表达式.constant(compValue,compValue.GetType());
表达式相等=表达式。相等(属性,常量);
表达式谓词=
Lambda(等式,参数);
返回谓词;
}
在我的用户类中,我有一个静态方法:
public static Expression<Func<Document, bool>> SubQuery(string property,
string targetValue)
{
var predicate = PredicateBuilder.True<User>();
predicate = predicate.And<User>(Extensions.AdHoc<User>(property, targetValue));
Expression<Func<Document, bool>> userSelector =
doc => doc.Users
.AsQueryable()
.Any(predicate);
var docParm = Expression.Parameter(typeof(Document), "appDoc");
var body = Expression.Invoke(userSelector, docParm);
var docPredicate = PredicateBuilder.True<Document>();
docPredicate = docPredicate.And<Document>(Expression.Lambda<Func<Document, bool>>(body, docParm));
return docPredicate;
}
公共静态表达式子查询(字符串属性,
字符串targetValue)
{
var predicate=PredicateBuilder.True();
谓词=谓词和(Extensions.AdHoc(property,targetValue));
表达式用户选择器=
doc=>doc.Users
.AsQueryable()
.任何(谓语);
var docParm=Expression.Parameter(typeof(Document),“appDoc”);
var body=Expression.Invoke(userSelector,docParm);
var docPredicate=PredicateBuilder.True();
docPredicate=docPredicate.And(Expression.Lambda(body,docParm));
返回docPredicate;
}
缺点是我在用户类本身中包含了子查询功能。它完成了任务,但是如果有人有任何建议或更好的方法来使用泛型,这样我就不必在我的用户类中包含这个静态方法,我很想听听你的意见。有趣-如果我理解这篇文章,你可以提前注册你的查询吗?你用过这种方法吗?对;您可以在编译之前生成查询。我在精神上使用了这种方法,但没有使用这个特定的工具包。
public static Expression<Func<T, bool>> AdHoc<T>
(string columnName, object compValue)
{
// Determine type of parameter
ParameterExpression parameter = Expression.Parameter(typeof(T), "x");
// Target to compare to
Expression property = Expression.Property(parameter, columnName);
// The value to match
Expression constant = Expression.Constant(compValue, compValue.GetType());
Expression equality = Expression.Equal(property, constant);
Expression<Func<T, bool>> predicate =
Expression.Lambda<Func<T, bool>>(equality, parameter);
return predicate;
}
public static Expression<Func<Document, bool>> SubQuery(string property,
string targetValue)
{
var predicate = PredicateBuilder.True<User>();
predicate = predicate.And<User>(Extensions.AdHoc<User>(property, targetValue));
Expression<Func<Document, bool>> userSelector =
doc => doc.Users
.AsQueryable()
.Any(predicate);
var docParm = Expression.Parameter(typeof(Document), "appDoc");
var body = Expression.Invoke(userSelector, docParm);
var docPredicate = PredicateBuilder.True<Document>();
docPredicate = docPredicate.And<Document>(Expression.Lambda<Func<Document, bool>>(body, docParm));
return docPredicate;
}