加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 当查询仅由属性不同时,如何解决LINQ to Entity查询重复?

发布时间:2020-12-15 22:43:26 所属栏目:百科 来源:网络整理
导读:我有两个DbSets,Foo和Bar. Foo有一个标识字符串属性FooName,而Bar有一个标识字符串属性BarName. 我正在设计一个非常简单的搜索功能,其中用户的查询字词可以等于或包含在识别名称中. 所以我有两种方法(大大简化): public ActionView SearchFoo(string query)
我有两个DbSets,Foo和Bar. Foo有一个标识字符串属性FooName,而Bar有一个标识字符串属性BarName.

我正在设计一个非常简单的搜索功能,其中用户的查询字词可以等于或包含在识别名称中.

所以我有两种方法(大大简化):

public ActionView SearchFoo(string query) 
{
    var equalsQuery = db.Foo.Where(f => f.FooName.Equals(query));
    var containsQuery = db.Foo.Where(f => f.FooName.Contains(query)).Take(10); // Don't want too many or else a search for "a" would yield too many results

    var result = equalsQuery.Union(containsQuery).ToList();
    ... // go on to return a view
}


public ActionView SearchBar(string query) 
{
    var equalsQuery = db.Bar.Where(f => f.BarName.Equals(query));
    var containsQuery = db.Bar.Where(f => f.BarName.Contains(query)).Take(10); // Don't want too many or else a search for "a" would yield too many results

    var result = equalsQuery.Union(containsQuery).ToList();
    ... // go on to return a view
}

显然我想要一些辅助方法,如下所示:

public IList<T> Search<T>(string query,DbSet<T> set) 
{
    var equalsQuery = set.Where(f => ???.Equals(query));
    var containsQuery = set.Where(f => ???.Contains(query)).Take(10); // Don't want too many or else a search for "a" would yield too many results

    var result = equalsQuery.Union(containsQuery).ToList();
    ... // go on to return a view
}

我最初尝试添加一个Func< T,string>到搜索参数,我可以使用f => f.FooName和b => b.BarName,但LINQ to Entities在执行查询期间不支持lambda表达式.

我一直在摸索如何提取这种重复.

解决方法

您可以使用Expression< Funt< T,string>>实现此目的.

public IList<T> Search<T>(string query,DbSet<T> set,Expression<Func<T,string>> propExp)
{
    MethodInfo method = typeof(string).GetMethod("Contains",new[] { typeof(string) });
    ConstantExpression someValue = Expression.Constant(query,typeof(string));
    MethodCallExpression containsMethodExp = 
             Expression.Call(propExp.Body,method,someValue);
    var e = (Expression<Func<T,bool>>)
              Expression.Lambda(containsMethodExp,propExp.Parameters.ToArray());
    var containsQuery = set.Where(e).Take(10);

    BinaryExpression equalExpression = Expression.Equal(propExp.Body,someValue);
    e = (Expression<Func<T,bool>>)
                 Expression.Lambda(equalExpression,propExp.Parameters.ToArray());

    var equalsQuery =  set.Where(e);

    var result = equalsQuery.Union(containsQuery).ToList();
}

那你就叫它:

Search ("myValue",fooSet,foo=>foo.FooName);

如果您可以使用静态方法,那么您可以将其作为扩展方法:

public static IList<T> Search<T>(this DbSet<T> set,string query,string>> propExp)

并称之为:

FooSet.Search ("myValue",foo=>foo.FooName);

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读