字符串值不为 null 或空的 LINQ 语法

问题描述 投票:0回答:6

我正在尝试像这样进行查询...

query.Where(x => !string.IsNullOrEmpty(x.PropertyName));

但是失败了...

所以现在我已经实现了以下内容,它有效......

query.Where(x => (x.PropertyName ?? string.Empty) != string.Empty);

LINQ 是否有更好(更原生?)的方式来处理这个问题?

编辑

道歉!不包括提供程序...这是使用 LINQ to SQL

linq linq-to-sql
6个回答
50
投票

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帖子


18
投票

这在 Linq2Objects 上不会失败,但对于 Linq2SQL 会失败,所以我假设您正在谈论 SQL 提供程序或类似的东西。

原因与 SQL 提供程序处理 lambda 表达式的方式有关。它并不将其视为函数

Func<P,T>
,而是表达式
Expression<Func<P,T>>
。它获取该表达式树并将其转换为实际的 SQL 语句,并将其发送到服务器。

翻译器知道如何处理基本运算符,但不知道如何处理对象上的方法。它不知道

IsNullOrEmpty(x)
会翻译为
return x == null || x == string.empty
。必须显式完成此操作才能转换为 SQL。


2
投票

这可以很好地与 Linq to Objects 配合使用。但是,某些 LINQ 提供程序难以将 CLR 方法作为查询的一部分运行。对于某些数据库提供商来说尤其如此。

问题在于数据库提供程序尝试将 LINQ 查询移动并编译为数据库查询,以防止通过网络拉取所有对象。这是一件好事,但有时会限制谓词的灵活性。

不幸的是,如果不检查提供程序文档,就很难始终准确地知道提供程序将直接支持或不支持哪些内容。看起来您的提供程序允许比较,但不允许字符串检查。我猜想,就您的情况而言,这可能是您能找到的最好的方法。 (除了创建“string.Empty”实例进行比较之外,这实际上与 IsNullOrEmpty 检查没有什么不同,但这很小。)


0
投票

... 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' '

0
投票

如果您想将集合的类型从可空类型

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
的字符串列表。


0
投票

如果您使用 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;
    }
© www.soinside.com 2019 - 2024. All rights reserved.