bsa*_*egh 0 c# linq entity-framework expression-trees
我最近发布了一个关于如何编写自定义表达式树的问题(虽然我没有意识到那是我当时要求的).现在我试图使用Scott Chamberlain提供的答案来创建另一种通用方法.
我正在使用Entity Framework并且有几个实体可以通过"Name"属性进行过滤.它并不总是名为Name,但基本上就是它.
实际的过滤方法比简单的包含或开始更复杂.它更像是一个Starts With,然后将包含搜索文本的名称的任何记录追加到列表的末尾.
由于有太多实体需要执行此过滤器,我希望能够创建一个将该过滤器应用于预编译查询的扩展方法.
我想能打电话
someQuery.ContainsName(x => x.Name, filter.Name);
Run Code Online (Sandbox Code Playgroud)
我有一个看起来像这样的扩展方法
public static IQueryable<T> ContainsName<T>(this IQueryable<T> query, Expression<Func<T, string>> selector, string matchingName)
{
var name = Expression.Constant(matchingName);
var selectorBody = selector.Body;
var propertyName = (selectorBody as MemberExpression).Member.Name;
var propExpression = Expression.Parameter(typeof(string), propertyName);
var selectorParameters = selector.Parameters;
Expression check = Expression.Call(typeof(GenericNameFilter).GetMethod("IsMatch"), propExpression, name);
var lambada = Expression.Lambda<Func<T, bool>>(check, selectorParameters);
return query.Where(lambada)
}
Run Code Online (Sandbox Code Playgroud)
IsMatch只接受2个字符串并返回一个bool.这不是该方法的最终游戏,但我希望能够让IsMatch的简单版本正常工作,然后我会扩展它.
当我在结果上调用ToList时,我得到一个例外.
"LINQ to Entities无法识别方法'Boolean IsMatch(System.String,System.String)'方法,并且此方法无法转换为商店表达式."
从我所做的搜索中我相信我想要做的事情是可能的,我只是做错了.这是我设置表达式树的方式吗?是IsMatch方法吗?一切都是错的吗?
问题的关键在于您无法编写导致代码运行的查询操作,因为数据库显然无法在其数据上运行C#代码.
您的扩展方法向查询管道添加lambda调用; 你打算将它解决为IsMatch方法的一些重载.但是,这对数据库没有任何意义,因此EF查询提供程序会告诉您它无法转换您写入SQL的内容.不幸的是,没有办法解决这个问题.
相同的代码在LINQ to对象上运行得很好,因为在那种情况下编译器当然可以安排调用你的方法.
| 归档时间: |
|
| 查看次数: |
392 次 |
| 最近记录: |