如何保持干爽,同时使用LINQ到实体和辅助方法? [英] How to stay DRY whilst using LINQ to Entities and helper methods?
问题描述
比方说,我有决定是否某些字符串匹配,像这样的一个特殊的方式:
Lets say that I have a particular way of deciding whether some strings "match", like this:
public bool stringsMatch(string searchFor, string searchIn)
{
if (string.IsNullOrEmpty(searchFor))
{
return true;
}
return searchIn != null &&
(searchIn.Trim().ToLower().StartsWith(searchFor.Trim().ToLower()) ||
searchIn.Contains(" " + searchFor));
}
我想拉匹配了使用LINQ to实体和这个数据库帮手。然而,当我试试这个:
I would like to pull matches out of a database using Linq To Entities and this helper. However, when I try this:
IQueryable<Blah> blahs = query.Where(b => stringsMatch(searchText, b.Name);
我得到LINQ到实体无法识别方法......
I get "LINQ to Entities does not recognize the method..."
如果我重新写代码:
IQueryable<Blah> blahs = query.Where(b =>
string.IsNullOrEmpty(searchText) ||
(b.Name != null &&
(b.Name.Trim().ToLower().StartsWith(searchText.Trim().ToLower()) ||
b.Name.Contains(" " + searchText)));
这在逻辑上等同,那么事情做工精细的问题是,该代码并不像。可读了,我必须重新写为每个不同的实体,我想匹配
Which is logically equivalent, then things work fine. The problem is that the code isn't as readable, and I have to re-write it for each different entity I want to match.
据我可以从喜欢的this 之一,我想什么这样做是不可能的时刻,但我希望我失去了一些东西,我是谁?
As far as I can tell from questions like this one, what I want to do is impossible at the moment, but I'm hoping that I'm missing something, am I?
推荐答案
使用自由可用库调用 LINQKit (如@Eranga提到的)这个任务就变得合理。使用LINQKit我现在有代码如下:
Using a freely available library called LINQKit (as mentioned by @Eranga) this task becomes reasonable. Using LINQKit the code I have now looks like:
protected Expression<Func<T, bool>> stringsMatch(string searchFor, Expression<Func<T, string>> searchIn)
{
if (string.IsNullOrEmpty(searchFor))
{
return e => true;
}
return
e =>
(searchIn.Invoke(e) != null &&
(searchIn.Invoke(e).Trim().ToLower().StartsWith(searchFor.Trim().ToLower()) ||
searchIn.Invoke(e).Contains(" " + searchFor)));
}
和需要这样调用(注意AsExpandable()调用)
And needs to be called like this (note the AsExpandable() call)
IQueryable<Blah> blahs = query().AsExpandable().Where(StringsMatch(searchText, b => b.Name));
神奇的部分是searchIn.Invoke(E)的调用和使用AsExpandable(中),这增加了一层包装,使他们的工作。
The magic parts are the searchIn.Invoke(e) calls and the use of AsExpandable() which adds a wrapper layer that allows them to work.
AsExpandable()位进行了详细原作者的这里。
The AsExpandable() bit is explained in detail by the original author here.
请注意,我在一些细节上还是有点朦胧表达式,所以请添加评论/编辑这个答案,如果它可以变得更好/更短/清晰。
Note that I'm still a bit hazy on some of the details of expressions, so please add a comment/edit this answer if it can be made better/shorter/clearer.
这篇关于如何保持干爽,同时使用LINQ到实体和辅助方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!