• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    扩展 Entity Framework支持复杂的过滤条件(多个关键字模糊匹配)
    之前遇到一个棘手的Linq to EF查询的技术问题,现有产品表Product,需要根据多个关键字模糊匹配产品名称, 现将解决方案分享出来。

    问题描述
    根据需求,我们需要编写如下的SQL语句来查询产品
    复制代码 代码如下:

    select * from dbo.Product
    where
    (ProductName like 'Product1%' or
    ProductName like 'Product2%')

    如何将以上的SQL语句转换成EF的写法呢?
    方案一
    可以使用Union,将以上SQL语句转换成以下的形式:
    复制代码 代码如下:

    select * from dbo.Product
    where
    ProductName like 'Product1%'
    UNION
    select * from DocutapCMS.dbo.Product
    where
    ProductName like 'Product2%'

    然后将上路SQL换成Linq To EF就非常简单了,再此就不贴出来了。但每个条件都要写一个Query,工作量大。如果条件太多,生成的SQL语句也非常大,并且写起来很费力。

    方案二
    我们从Linq To EF的Contains功能得到启发,Linq To EF 会将Contains转换成IN表达式。
    那么我们可不可以直接写Expression,将条件转换成上述SQL语句呢?答案是肯定的。以下就是实现上述方案的具体Linq To EF扩展。
    复制代码 代码如下:

    public static ExpressionFuncTElement, bool>> BuildContainsExpressionTElement, TValue>(ExpressionFuncTElement, TValue>> valueSelector,
      IEnumerableTValue> values)
    {
      var startsWithMethod = typeof (string).GetMethod("StartsWith", new[] { typeof(string) });
      var startWiths = values.Select(value => (Expression)Expression.Call(valueSelector.Body, startsWithMethod, Expression.Constant(value, typeof(TValue))));
      var body = startWiths.AggregateExpression>(((accumulate, equal) => Expression.Or(accumulate, equal)));
      var p = Expression.Parameter(typeof(TElement));
      return Expression.LambdaFuncTElement, bool>>(body, p);
    }

    用法:
    复制代码 代码如下:

    private static void QueryProducts(IQueryableProduct> query)
    {
    var productNames = new string[] {"P1", "P2"};
    var query1 = from a in query.Where(BuildContainsExpressionProduct, string>(d=>d.ProductName, productNames))
    select a;
    var items2 = query1.ToList();
    }
    private static void QueryProducts(IQueryableProduct> query)
    {
    var productNames = new string[] {"P1", "P2"};
    var query1 = from a in query.Where(BuildContainsExpressionProduct, string>(d=>d.ProductName, productNames))
    select a;
    var items2 = query1.ToList();
    }

    创建扩展方法,让调用变得简单
    复制代码 代码如下:

    public static IQueryableTElement> WhereOrLikeTElement, TValue>(this IQueryableTElement> query,
      ExpressionFuncTElement, TValue>> valueSelector, IEnumerableTValue> values)
    {
    return query.Where(BuildContainsExpressionTElement, TValue>(valueSelector, values));
    }
    private static void QueryProducts2(IQueryableProduct> query)
    {
    var productNames = new string[] {"P1", "P2"};
    query.WhereOrLike(d=>d.ProductName, productNames).ToList();
    }

    通过SQL Profile 监视生成的SQL语句
    复制代码 代码如下:

    -- Region Parameters
    DECLARE @p0 NVarChar(3) = 'P1%'
    DECLARE @p1 NVarChar(3) = 'P2%'
    -- EndRegion
    SELECT [t0].[Id], [t0].[ProductName]
    FROM [Product] AS [t0]
    WHERE ([t0].[ProductName] LIKE @p0) OR ([t0].[ProductName] LIKE @p1)
    您可能感兴趣的文章:
    • 详解如何在ASP.NET Core中应用Entity Framework
    • NopCommerce架构分析之(三)EntityFramework数据库初试化及数据操作
    • C# Entity Framework中的IQueryable和IQueryProvider详解
    • 使用Entity Framework(4.3.1版本)遇到的问题整理
    • Entity Framework之DB First方式详解
    上一篇:C# 递归函数详细介绍及使用方法
    下一篇:Sqlite 常用函数封装提高Codeeer的效率
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

    扩展 Entity Framework支持复杂的过滤条件(多个关键字模糊匹配) 扩展,Entity,Framework,支持,