2010-06-08 78 views
0

我遇到了“问题”我不太确定我是否理解实体框架。我正在使用实体框架4,并尝试使用TDD方法。因此,我最近使用Repository模式实现了一个搜索功能。对于我的测试项目,我正在实现我的存储库接口,并有一组“假”对象数据用于测试目的。实体框架和SQL与使用ToLower的对象之间的差异

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

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

然而,当我跑我的测试情况下,如果我的情况不匹配的基本数据,其中未填充的结果。我尝试了解一下我认为是一个问题。为了清楚我的想法,我进行了一次运行,并想知道与EF相同的代码是否可以用于SQL后端数据库,因为SQL将明确支持like命令,并且按照我的预期执行,并使用相同的逻辑。

我明白为什么EF对数据库后端支持Contains子句。但是,我很惊讶我的单元测试没有。任何想法为什么除了SQL服务器支持类似子句时,我使用的是对象而不是数据库服务器?

谢谢!

约翰

回答

4

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

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

...如果f.Bar恰好是一个空引用,这句话仍然会工作得很好,因为f.Bar.Something将合并到null 。如果您考虑SQL的工作方式,使用LEFT JOIN,这应该不会令人惊讶。另一方面,在LINQ到对象中,相同的Where表达式会抛出一个空引用异常。

正如您发现的,还有其他方面的差异。区分大小写是一个。当执行LINQ to Entities查询时,它将转换为SQL。根据数据库中定义的归类规则以及SQL执行相等比较。要为数据库自定义排序规则,通常需要为列选择特定排序规则。另一方面,为了自定义对象的排序规则,通常需要传递一个比较函数,这在LINQ to Entities中永远不会被接受,因为函数(而不是表达式)不能转换为SQL。

有,然而,一个办法做到不区分大小写的比较,这两个LINQ提供程序的工作原理:

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