C# 林氏;String.ToLower()奇怪的行为

C# 林氏;String.ToLower()奇怪的行为,c#,linq,string,wcf-ria-services,C#,Linq,String,Wcf Ria Services,我在服务器端有一个查询,它从zipcode表返回不同城市的列表。 我正在使用WCF RIA服务。 以下查询在provincename==“” 为什么查询没有返回任何内容?尝试使用DB管理工具检查生成的SQL,或者在查询表达式末尾调用.ToTraceString() 参考: 我们在工作中使用ToTraceString,使用扩展名: public static IQueryable<T> TraceSql<T>(this IQueryable<T> query)


我在服务器端有一个查询,它从zipcode表返回不同城市的列表。
我正在使用WCF RIA服务。
以下查询在
provincename==“”


为什么查询没有返回任何内容?

尝试使用DB管理工具检查生成的SQL,或者在查询表达式末尾调用.ToTraceString()

参考:

我们在工作中使用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;
}
公共静态IQueryable TraceSql(此IQueryable查询)
{
var sql=((System.Data.Objects.ObjectQuery)query).ToTraceString();
//在这里执行您想要的任何sql日志记录,例如(用于web)
//(通过访问站点内的trace.axd进行查看)
HttpContext.Current.Trace.Write(“sql”,sql);
返回查询;
}
然后可按如下方式使用:

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();
}
public IQueryable GetCities(字符串provinceName)
{
返回此.ObjectContext.ZipCodes.Where(z=>z.Province.ToLower().Contains(provinceName.ToLower()))
.GroupBy(z=>z.City)
.Select(g=>g.FirstOrDefault())
.Select(zc=>newcitypm(){ID=zc.ID,Name=zc.City})
.TraceSql();
}
请原谅我的任何打字错误,这是出于记忆。希望它能帮助你理解你的问题。

解释 我也有同样的问题,我发现了为什么会发生这种情况。运行SQL Profiler时,我发现从LINQ到SQL生成的WHERE语句在每种情况下都非常不同

.Where(z => z.Province.Contains(provinceName))
将在SQL中呈现为:

WHERE [Province] LIKE N'%%'
WHERE ( CAST( CHARINDEX(LOWER(N''), LOWER([Province])) AS int)) > 0
正如您所经历的,
如“%”
将匹配任何非空结果

.
但是,

.Where(z => z.Province.ToLower().Contains(provinceName.ToLower()))
将在SQL中呈现为:

WHERE [Province] LIKE N'%%'
WHERE ( CAST( CHARINDEX(LOWER(N''), LOWER([Province])) AS int)) > 0
这与“%”之类的
非常不同。SQL实际上是在查看字符串
中的字符。空的
位于字符串中。空字符串上的
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 });
}
public IQueryable GetCities(字符串provinceName)
{
var lowerProvinceName=String.IsNullOrEmpty(provinceName)?String.Empty:provinceName.ToLower();
返回此.ObjectContext.ZipCodes.Where(z=>z.Province.ToLower().Contains(lowerProvinceName))
.GroupBy(z=>z.City)
.Select(g=>g.FirstOrDefault())
.Select(zc=>newcitypm(){ID=zc.ID,Name=zc.City});
}

通过这样构造代码,如果provinceName是空字符串,LINQ to SQL将呈现为“%”之类的
,否则将呈现为
CHARINDEX
。如果传入的是空值,它也会有所帮助。

这对我很有效,如果您喜欢,请尝试一下

其中(p=>p.Email.ToUpper().Equals(muser.Email.ToUpper())


注意:我是根据Oracle查询它的

省是一个字符串,对吗?因此,您正在调用String.Contains(String),它检查省是否包含给定的子字符串。在您的情况下,当provinceName为空字符串时,所有省份都将包含该字符串,并且所有省份都将匹配。这真的是你想要的吗?ToLower()在第二种情况下使用它的方式不应改变结果。您确定参数的值吗?是的,我同意-我认为您的查询不正确。通过变量“ObjectContext”的外观,您可以使用EF。您是否尝试运行SQL配置文件以查看实际生成的T-SQL?将极大地帮助您解决问题(并帮助您理解您的查询)。甚至LinqPad也可以。RPM1984:Just
ToTraceString()
就可以了;不需要涉及外部程序。我希望查询返回省为空字符串时的所有城市(所有省份),如果不是空字符串,则返回该省内的城市。谢谢您的帮助。我认为TraceSql应该是TraceSql。