【发布时间】:2018-08-29 18:01:31
【问题描述】:
我想实现下面的方法
public static class Filters
{
public static Expression<Func<T,bool>> ContainsText<T>(
string text, params Expression<Func<T,string>>[] fields)
{
//..
}
}
如果我想(例如)找到名字中包含“Mark”或父亲名字中包含“Mark”的人,我可以这样做:
var textFilter = Filters.ContainsText<Individual>("Mark", i=>i.FirstName, i=>i.LastName, i=>i.Father.FirstName, i => i.Father.LastName);
var searchResults = _context.Individuals.Where(textFilter).ToList();
我的最终目标是能够创建一个ContainsTextSpecification 来简化我可以这样使用的基于文本的过滤:
var textSpec = new ContainsTextSpecification<Individual>(i=>i.FirstName, i=> i.LastName, i=>i.DepartmentName, i=>i.SSN, i=>i.BadgeNumber);
textSpec.Text = FormValues["filter"];
var results = individuals.Find(textSpec);
我发现了一些让我接近的东西here,但我希望能够通过使用Func<T,string> 而不仅仅是名称来指定我想要过滤的字段领域的。 (编辑:我希望能够指定要检查的 -values-,而不是字段的名称)
static Expression<Func<T, bool>> GetExpression<T>(string propertyName, string propertyValue)
{
var parameterExp = Expression.Parameter(typeof(T), "type");
var propertyExp = Expression.Property(parameterExp, propertyName);
MethodInfo method = typeof(string).GetMethod("Contains", new[] { typeof(string) });
var someValue = Expression.Constant(propertyValue, typeof(string));
var containsMethodExp = Expression.Call(propertyExp, method, someValue);
return Expression.Lambda<Func<T, bool>>(containsMethodExp, parameterExp);
}
var results = individualRepo.Get(textSpec);
【问题讨论】:
-
为什么不直接使用
static Expression<Func<T, bool>> GetExpression<T>(Func<T, string> propertyName, string propertyValue)? -
EF 需要能够使用函数返回的表达式来创建 SQL 查询。如果我使用对 c# 函数(而不是表达式)的调用来构建表达式,那么 EF 将不知道如何将查询转换为 SQL。
-
我知道,但没有什么能阻止您在将
Func的结果传递给Expression.Property之前获得结果 -
@CamiloTerevinto 与接受属性的字符串名称相比,接受返回属性字符串名称的方法有什么好处?
-
@Servy 好吧,“我希望能够使用 Func
而不仅仅是字段名称来指定我想要过滤的字段。”
标签: c# entity-framework linq functional-programming