使用LINQ to Entities和帮助方法时如何保持DRY? [英] How to stay DRY whilst using LINQ to Entities and helper methods?

查看:117
本文介绍了使用LINQ to Entities和帮助方法时如何保持DRY?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

让我们说,我有一种特定的方式来决定一些字符串是否匹配,如下所示:

  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 Entities从数据库中拉出匹配项,帮手。但是,当我尝试这样做:

  IQueryable&Blan& blahs = query.Where(b => stringsMatch(searchText,b.Name); 

我得到LINQ to Entities不认识方法...



如果我重写代码如下:

  IQueryable< Blah> blahs = query.Where(b => 
string.IsNullOrEmpty(searchText)||
(b.Name!= null& &
(b.Name.Trim()。ToLower()。StartsWith(searchText.Trim()。ToLower())||
b.Name.Contains(+ searchText))) ;

这在逻辑上是等效的,那么事情就行了,问题是代码不是可以读取,我必须为每个要匹配的不同实体重新编写它。



从我可以从这是一个,我想要现在是不可能的,但我希望我错过了一些东西I?

解决方案

使用一个免费的库,名为 LINQKit (由@Eranga提到)这个任务变得合理。使用LINQKit我现在的代码如下:

  protected Expression< Func< T,bool>> stringMatch(string searchFor,Expression< Func< T,string>> searchIn)
{
if(string.IsNullOrEmpty(searchFor))
{
return e =>真正;
}

return
e =>
(searchIn.Invoke(e)!= null&&
(searchIn.Invoke(e).Trim()。ToLower()。StartsWith(searchFor.Trim()。ToLower() ||
searchIn.Invoke(e).Contains(+ searchFor)));
}

需要像这样调用(注意AsExpandable()调用) / p>

  IQueryable< Blah> blahs = query()。AsExpandable()。Where(StringsMatch(searchText,b => b.Name)); 

魔法部分是searchIn.Invoke(e)调用和使用AsExpandable()一个允许他们工作的包装层。



AsExpandable()位由原作者详细解释这里



请注意,我还有一些朦胧的一些细节表达式,所以请添加评论/编辑这个答案,如果它可以做得更好/更短/更清晰。


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));
}

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);

I get "LINQ to Entities does not recognize the method..."

If I re-write the code as:

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.

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?

解决方案

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)));
}

And needs to be called like this (note the AsExpandable() call)

IQueryable<Blah> blahs = query().AsExpandable().Where(StringsMatch(searchText, b => b.Name));

The magic parts are the searchIn.Invoke(e) calls and the use of AsExpandable() which adds a wrapper layer that allows them to work.

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 to Entities和帮助方法时如何保持DRY?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆