我正在尝试像这样进行查询...
query.Where(x => !string.IsNullOrEmpty(x.PropertyName));
但是失败了...
所以现在我已经实现了以下内容,它有效......
query.Where(x => (x.PropertyName ?? string.Empty) != string.Empty);
LINQ 是否有更好(更原生?)的方式来处理这个问题?
编辑
道歉!不包括提供程序...这是使用 LINQ to SQL
http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=367077
问题陈述
可以编写 LINQ to SQL 来获取给定字段中具有 null 或空字符串的所有行,但无法使用 string.IsNullOrEmpty 来执行此操作,即使许多其他字符串方法映射到 LINQ to SQL。
建议的解决方案
允许在 LINQ to SQL where 子句中使用 string.IsNullOrEmpty,以便这两个查询具有相同的结果:
var fieldNullOrEmpty =
from item in db.SomeTable
where item.SomeField == null || item.SomeField.Equals(string.Empty)
select item;
var fieldNullOrEmpty2 =
from item in db.SomeTable
where string.IsNullOrEmpty(item.SomeField)
select item;
其他阅读:
1.DevArt
2.Dervalp.com
3.StackOverflow帖子
这在 Linq2Objects 上不会失败,但对于 Linq2SQL 会失败,所以我假设您正在谈论 SQL 提供程序或类似的东西。
原因与 SQL 提供程序处理 lambda 表达式的方式有关。它并不将其视为函数
Func<P,T>
,而是表达式Expression<Func<P,T>>
。它获取该表达式树并将其转换为实际的 SQL 语句,并将其发送到服务器。
翻译器知道如何处理基本运算符,但不知道如何处理对象上的方法。它不知道
IsNullOrEmpty(x)
会翻译为 return x == null || x == string.empty
。必须显式完成此操作才能转换为 SQL。
这可以很好地与 Linq to Objects 配合使用。但是,某些 LINQ 提供程序难以将 CLR 方法作为查询的一部分运行。对于某些数据库提供商来说尤其如此。
问题在于数据库提供程序尝试将 LINQ 查询移动并编译为数据库查询,以防止通过网络拉取所有对象。这是一件好事,但有时会限制谓词的灵活性。
不幸的是,如果不检查提供程序文档,就很难始终准确地知道提供程序将直接支持或不支持哪些内容。看起来您的提供程序允许比较,但不允许字符串检查。我猜想,就您的情况而言,这可能是您能找到的最好的方法。 (除了创建“string.Empty”实例进行比较之外,这实际上与 IsNullOrEmpty 检查没有什么不同,但这很小。)
... 12 年前:) 但仍然有人可能会发现它有帮助:
通常检查空白也很好
query.Where(x => !string.IsNullOrWhiteSpace(x.PropertyName));
它将转换为sql:
WHERE [x].[PropertyName] IS NOT NULL AND ((LTRIM(RTRIM([x].[PropertyName])) <> N'') OR [x].[PropertyName] IS NULL)
或其他方式:
query.Where(x => string.Compare(x.PropertyName," ") > 0);
将转换为sql为:
WHERE [x].[PropertyName] > N' '
如果您想将集合的类型从可空类型
IEnumerable<T?>
更改为非空类型IEnumerable<T>
,您可以使用.OfType<T>()
。
.OfType<T>()
将删除空值并返回 T
类型的列表。
示例:如果您有一个可为空字符串的列表:
List<string?>
,您可以使用 string
将列表的类型更改为 OfType<string()
,如下例所示:
List<string?> nullableStrings = new List<string?> { "test1", null, "test2" };
List<string> strings = nullableStrings.OfType<string>().ToList();
// strings now only contains { "test1", "test2" }
这将产生仅包含
test1
和 test2
的字符串列表。
如果您使用 SQL 和 LINQ,那么您必须使用以下代码片段
public static string ConcatString(string seperator, List<string?> strings)
{
string concatedString = string.Empty;
strings.ForEach(s =>
{
if (s != null && s != string.Empty)
{
if (concatedString == string.Empty)
{
concatedString = s;
}
else
{
concatedString = concatedString + seperator + s;
}
}
});
return concatedString;
}