【问题标题】:Unit Test method with EF.Functions.Contains()带有 EF.Functions.Contains() 的单元测试方法
【发布时间】:2019-04-05 10:00:06
【问题描述】:

我有一个包含对EF.Functions.Contains 的调用的方法。现在我想用 InMemory 数据库为这个方法编写单元测试,但我立即得到以下异常System.InvalidOperationException : The 'Contains' method is not supported because the query has switched to client-evaluation.

我的方法是这样的

var attributeValues = Context.AssetAttributeValues
                                         .Include(a => a.AssetAttribute)
                                         .Include(a => a.Asset)
                                         .Where(i => EF.Functions.Contains(i.Value, searchString));

我知道引发此异常是因为与生产性 SQL Server 实例相比,我的 InMemory 数据库上没有全文索引,但是如何在 InMemory 数据库上获得相同的索引?

有没有办法解决这个异常?

【问题讨论】:

  • 一个解决方案是使用:.Where(i => i.Value.Contains(searchString));
  • @TanvirArjel 不幸的是,这是没有选择的,因为这是一个巨大的表,所以我不得不创建一个全文索引。使用您的解决方案,sql 只会进行 LIKE '%searchstring%' 操作,这绝对不快...

标签: c# entity-framework unit-testing ef-core-2.2


【解决方案1】:

就像你说的,EF.Functions.Contains 不能在 InMemory 数据库中使用。

一种解决方法是使用IsSqlServer() 检查您是否针对 SQL Server 或 InMemory 提供程序运行。

if(Context.IsSqlServer())  
    return Context.AssetAttributeValues
                                         .Include(a => a.AssetAttribute)
                                         .Include(a => a.Asset)
                                         .Where(i => EF.Functions.Contains(i.Value, searchString));
else
    return Context.AssetAttributeValues
                                         .Include(a => a.AssetAttribute)
                                         .Include(a => a.Asset)
                                         .Where(i => i.Value.Contains(searchString));

【讨论】:

  • 编写代码以便该代码可以通过单元测试并不是一个好主意。因为那测试证明了什么?
  • @CodeCaster:我同意,这不是解决方案,只是问题中提出的问题的解决方法。事实上,通过这样做,您将一个未经测试的 if 块运送到生产环境。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-10
  • 1970-01-01
  • 2019-02-03
  • 2011-07-13
相关资源
最近更新 更多