实体框架以及使用ToLower在SQL和对象之间包含的差异

时间:2010-06-08 03:54:09

标签: entity-framework entity-framework-4

我遇到了“问题”我不太确定我对Entity Framework有所了解。我正在使用Entity Framework 4并尝试使用TDD方法。因此,我最近使用Repository模式实现了搜索功能。对于我的测试项目,我正在实现我的存储库接口,并且有一组我用于测试目的的“假”对象数据。

我遇到了一个问题,试图让Contains子句用于案例不变搜索。我的测试和针对数据库使用的存储库类的代码片段如下:

if (!string.IsNullOrEmpty(Description))
{
     items = items.Where(r => r.Description.ToLower().Contains(Description.ToLower()));
}

但是,当我运行我的测试用例时,如果我的案例与基础数据不匹配,则未填充的结果。我试着研究一下我认为是一个问题。为了清楚我的想法,我去了一个运行,想知道与EF相同的代码是否可以对SQL后端数据库起作用,因为SQL将显式支持like命令并且它按照我的预期执行,使用相同的逻辑。

我理解为什么针对数据库后端的EF支持Contains子句。但是,我很惊讶我的单元测试没有。当我使用对象填充集合而不是数据库服务器时,除了SQL服务器支持like子句之外的任何想法?

谢谢!

约翰

1 个答案:

答案 0 :(得分:4)

LINQ to Entities和LINQ to Objects有不同的规则。就这么简单。例如,在LINQ to Entities中,我可以运行如下查询:

var foo = Context.Foos.Where(f => f.Bar.Something == bar);

...如果f.Bar碰巧是空引用,那么此语句仍然可以正常工作,因为f.Bar.Something将合并到null。如果您考虑SQL如何工作,使用LEFT JOIN,这应该不足为奇。另一方面,在LINQ to对象中,相同的Where表达式将抛出空引用异常。

正如您所发现的,还有其他不同之处。区分大小写是一个。执行LINQ to Entities查询时,它将转换为SQL。基于数据库中定义的排序规则以及SQL中执行平等比较。要自定义数据库的排序规则,通常要为列选择特定的排序规则。另一方面,要自定义对象的排序规则,通常会传递一个比较函数,该函数在LINQ to Entities中永远不会被接受,因为函数(与表达式相对)无法转换为SQL。

然而,有一种方法可以对LINQ提供程序进行不区分大小写的比较:

var foo = Context.Foos.Where(f => f.SomeString.Equals(someValue, StringComparison.OrdinalIgnoreCase));