2014-01-06 36 views
3

我使用Linq和Entity Framework Code First首先查询MS SQL数据库。要求是能够对该表运行WHERE SomeColumn LIKE '%sometext'子句。如何更改由linq-to-entities生成的sql?

此,从表面上看,是一个简单的要求,可以用一个简单的Linq查询这样来完成:

var results = new List<MyTable>(); 
using(var context = new MyContext()) 
{ 
    results = context.MyTableQueryable 
    .Where(x => x.SomeColumn.EndsWith("sometext")) 
    .ToList(); 
} 
// use results 

然而,这不是有效的做法。问题似乎是SomeColumn列不是varchar,而是char(31)。这意味着如果一个字符串保存在少于31个字符的列中,那么在字符串的末尾会添加空格以确保长度为31个字符,并且会对.EndsWith()查询产生影响。

我使用SQL事件探查器来查找从.EndsWith()方法中生成的确切的SQL。以下是我发现:

--previous query code removed for brevity 
WHERE [Extent1].[SomeColumn] LIKE N'%sometext' 

所以很有趣。我不确定在'%sometext'之前N是什么意思。 (我将在后面google一下。)但我知道,如果我采取相同的查询,并在SSMS没有N像这样运行:

--previous query code removed for brevity 
WHERE [Extent1].[SomeColumn] LIKE '%sometext' 

然后查询工作正常。有没有办法让Linq和Entity Framework从查询中删除N

+1

''N''基本上意味着它将你的字符串视为一个varchar,这可能是你的问题。 – Kippie

+0

[VARCHAR和NVARCHAR](http://stackoverflow.com/questions/144283/what-is-the-difference-between-varchar-and-nvarchar)。至于你得到的错误,它确实看起来很奇怪,而不是我遇到过的问题,但是我再次只在最近的数据库中使用'NVARCHAR'而没有问题。 – XN16

+0

@ XN16 - 我更喜欢nvarchar。不幸的是,我不能在这种情况下使用它。 – quakkels

回答

2

请试试这个...

.Where(x => x.SomeColumn.Trim().EndsWith("sometext")) 
+0

oof。谢谢,这工作。现在我需要将'.Trim()'方法写入我的表达式树生成器中......呃。我希望能避免这种情况。 :-) – quakkels

+0

@quakkels谢谢.. –

+0

对于那些有兴趣的,这会导致以下查询:'WHERE LTRIM(RTRIM([Extent1]。[SomeColumn]))LIKE N'%sometext'' – quakkels

1

只是跟我的同事谁也有类似的问题,看是否适合你了以下工作:

[Column(TypeName = "varchar")] 
public string SomeColumn 
{ 
    get; 
    set; 
} 

显然设置类型的列映射将强制查询将其识别为VARCHAR,其中字符串通常被解释为NVARCHAR

+0

这是打算生成一个列是varchar? (我无法更改现有的数据库。)或者,这是否意图导致EF将char(31)列作为varchar处理? – quakkels

+0

@quakkels我相信这是第二种选择,它会将其视为varchar。 – XN16

相关问题