Yeo*_*nho 4 c# linq string wcf-ria-services
我在服务器端有一个查询,它从一个zipcode表返回一个不同城市的列表.
我正在使用WCF RIA服务.
以下查询成功返回228个城市provincename == ""
public IQueryable<CityPM> GetCities(string provinceName)
{
return this.ObjectContext.ZipCodes.Where(z => z.Province.Contains(provinceName))
.GroupBy(z => z.City)
.Select(g => g.FirstOrDefault())
.Select(zc => new CityPM() { ID = zc.ID, Name = zc.City });
}
Run Code Online (Sandbox Code Playgroud)
但如果我使用如下的ToLower()方法,则查询返回0个城市provincename == ""
.
public IQueryable<CityPM> GetCities(string provinceName)
{
return this.ObjectContext.ZipCodes.Where(z => z.Province.ToLower().Contains(provinceName.ToLower()))
.GroupBy(z => z.City)
.Select(g => g.FirstOrDefault())
.Select(zc => new CityPM() { ID = zc.ID, Name = zc.City });
}
Run Code Online (Sandbox Code Playgroud)
为什么查询不返回任何内容?
尝试使用数据库管理工具检查生成的SQL,或者在查询表达式的末尾调用.ToTraceString().
参考:http://blog.aggregatedintelligence.com/2010/06/viewing-entity-framework-generated-sql.html
我们在使用扩展时使用ToTraceString:
public static IQueryable<T> TraceSql<T>(this IQueryable<T> query)
{
var sql = ((System.Data.Objects.ObjectQuery)query).ToTraceString();
// do whatever logging of sql you want here, eg (for web)
// (view by visiting trace.axd within your site)
HttpContext.Current.Trace.Write("sql", sql);
return query;
}
Run Code Online (Sandbox Code Playgroud)
然后可以使用如下:
public IQueryable<CityPM> GetCities(string provinceName)
{
return this.ObjectContext.ZipCodes.Where(z => z.Province.ToLower().Contains(provinceName.ToLower()))
.GroupBy(z => z.City)
.Select(g => g.FirstOrDefault())
.Select(zc => new CityPM() { ID = zc.ID, Name = zc.City })
.TraceSql();
}
Run Code Online (Sandbox Code Playgroud)
请原谅我的任何错别字,这是来自记忆.希望它能帮助您理解您的问题.
我遇到了同样的问题,我发现了为什么会发生这种情况。运行 SQL Profiler 我看到从LINQ to SQL生成的WHERE语句在每种情况下都非常不同。
.Where(z => z.Province.Contains(provinceName))
Run Code Online (Sandbox Code Playgroud)
将在 SQL 中呈现为:
WHERE [Province] LIKE N'%%'
Run Code Online (Sandbox Code Playgroud)
正如您所经历的,LIKE '%%'
将匹配任何非空结果。
.
然而,
.Where(z => z.Province.ToLower().Contains(provinceName.ToLower()))
Run Code Online (Sandbox Code Playgroud)
将在 SQL 中呈现为:
WHERE ( CAST( CHARINDEX(LOWER(N''), LOWER([Province])) AS int)) > 0
Run Code Online (Sandbox Code Playgroud)
这与LIKE '%%'
. SQL 本质上是查看string.Empty
字符串Province中的字符。CHARINDEX
空字符串的结果为 0,这就是没有返回结果的原因。
.
这有点骇人听闻,但它会起作用。仅.ToLower()
当字符串不为空时才调用。以下代码是一个应该适合您的示例。
public IQueryable<CityPM> GetCities(string provinceName)
{
var lowerProvinceName = String.IsNullOrEmpty(provinceName) ? string.Empty : provinceName.ToLower();
return this.ObjectContext.ZipCodes.Where(z => z.Province.ToLower().Contains(lowerProvinceName))
.GroupBy(z => z.City)
.Select(g => g.FirstOrDefault())
.Select(zc => new CityPM() { ID = zc.ID, Name = zc.City });
}
Run Code Online (Sandbox Code Playgroud)
通过像这样构造您的代码,LINQ to SQL将呈现为LIKE '%%'
好像ProvinceName是一个空字符串,否则它将呈现为CHARINDEX
. 如果传入空值,它也有帮助。