【问题标题】:C# expression works on the database, doesn't work in memoryC# 表达式适用于数据库,不适用于内存
【发布时间】:2019-08-07 08:47:05
【问题描述】:

我有一个带有实体的 .NET Core 2.2 应用程序,它从用户那里获取字符串输入,然后将其转换为表达式,最后根据它过滤一些数据。这是来自字符串的类构建表达式(基于this 文章):

 public async Task<Expression<Func<T, bool>>> GetLinqExpression<T>(string rule)
 {
     var options = ScriptOptions.Default.AddReferences(typeof(T).Assembly);
     return await CSharpScript.EvaluateAsync<Expression<Func<T, bool>>>(rule, options);
 }

在 db 上使用时,表达式按预期工作:

var linqExpression = await _linqService.GetLinqExpression<Item>(linqExpressionString);
var filteredItems = _dbContext.Items.Where(linqExpression).ToList();

但当我尝试使用Compile() 方法在内存中执行相同操作时,它不会。

var linqExpression = await _linqService.GetLinqExpression<Item>(linqExpressionString);
var items = _dbContext.Items.ToList();
var filteredItems = items.Where(linqExpression.Compile()).ToList();

在这种情况下,代码运行成功,但 filteredItems 集合为空。为什么它会这样?如何在内存中运行此表达式?

【问题讨论】:

  • 你在那个“linqExpressionString”中做了什么样的过滤?例如,当您匹配某个字符串值时,在内存中这将区分大小写,而数据库可能不区分大小写
  • @HansKesting 我正在测试的简单字符串输入是i =&gt; i.Description.Contains("a-store") || i.Description.Contains("astore") || i.Description.Contains("für store"),其中Descriptionstring 对象的string 属性。
  • @HansKesting 您的建议是正确的!问题在于区分大小写,查询i =&gt; i.Description.ToLower().Contains("a-store") || i.Description.ToLower().Contains("astore") || i.Description.ToLower().Contains("für store") 在内存中正常工作。请回答我的问题,以便我将其标记为已解决。

标签: c# .net sql-server .net-core


【解决方案1】:

在“内存中”和“数据库中”之间评估过滤器表达式的方式可能有所不同。特别是当您过滤字符串值时!

在内存中,字符串比较(value == "some value"value.Contains("some value"))区分大小写。

在数据库中,这取决于为该列/表/数据库设置的排序规则。默认情况下,这可能是不区分大小写的(在 SqlServer 中,排序规则上的“CI”后缀表示“不区分大小写”,而“AS”表示“区分重音”)

因此,数据库可能会返回比内存数据存储更多的记录。

【讨论】:

    猜你喜欢
    • 2013-05-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多