在 C# 中使用 LINQ 方法语法 (LINQ to SQL) 时发生异常

Posted

技术标签:

【中文标题】在 C# 中使用 LINQ 方法语法 (LINQ to SQL) 时发生异常【英文标题】:An exception occurred with using LINQ method syntax (LINQ to SQL) in C# 【发布时间】:2021-08-16 16:22:46 【问题描述】:

我在我的代码中使用 Linq to Sql 和方法语法从数据库中查询所有表。而且我今天遇到了一个奇怪的异常,这是我开始使用L2S以来第一次出现错误。

数据库表中有两列。 而“状态”一栏是映射到枚举类型的程序:1(Free),2(Loan)。

。数据库表架构如下。

。定义表类

private string Type;
private byte Status;

。查询码

string _qNote = string.Empty;
string _qStatus = string.Empty;
List<DefineTableClass> _List = _dbObj.Table.Select(_obj => _obj)
                            .Where(_obj => 
                            (string.IsNullOrWhiteSpace(_qNote) || _obj.Note == _qNote)
                            && (string.IsNullOrWhiteSpace(_qStatus) || Convert.ToInt32(_obj.Status) == Convert.ToInt32(_qStatus))
                            ).ToList();

异常发生在

Convert.ToInt32(_obj.Status) == Convert.ToInt32(_qStatus)

我想知道这条线应该在

(string.IsNullOrWhiteSpace(_qStatus)

由于 _qStatusEmpty,不应进行下一次检查。

【问题讨论】:

最可能的原因是string.IsNullOrWhiteSpace 不是Linq to SQL 支持的函数。试试string == "" || string == null Convert.ToInt32(_obj.Status) 也可能不受支持。您可以做的是尝试通过调用 ToList() 将 Linq to SQL 查询的结果具体化到列表中,然后将您的 Select 应用于结果列表; Linq to Objects 支持您尝试调用的所有方法。 @RobertHarvey 我确信 Linq to SQL 支持这两个功能。因为我有其他查询也是用这种方式从数据库中查询的,而且有效。 然后编辑您的问题以包含有效查询和无效查询之间的差异 【参考方案1】:

通过在 Queryable lambda 之外准备参数来改进您的查询:

string _qNote = string.Empty;
string _qStatus = string.Empty;

var query = _dbObj.Table.AsQueryable();

if (!string.IsNullOrWhiteSpace(_qNote))
    query = query.Where(_obj => _obj.Note == _qNote);

if (!string.IsNullOrWhiteSpace(_qStatus))

    var byteStatus = Convert.ToByte(_qStatus);
    query = query.Where(_obj => _obj.Status == byteStatus);


var _List = query.ToList();

它应该产生更有效的 SQL,并且可以避免不必要的转换。

【讨论】:

【参考方案2】:

我在我的问题中发现了类似的情况。

L2S 会检查 ALL where 条件,所以无论前面的检查我们认为应该通过,它都必须做(string.IsNullOrWhiteSpace(_qStatus),因为它是真的。

编写 L2S 的更好方法可能更少在语法中使用强制转换,就像 @SvyatoslavDanyliv 所说,在 Queryable lambda 之外准备参数可以防止我此时出现奇怪的逻辑问题。

参考:

Why isn't this short circuit is not working in linq to sql query?

Why isn't this short circuit in lambda working?

【讨论】:

以上是关于在 C# 中使用 LINQ 方法语法 (LINQ to SQL) 时发生异常的主要内容,如果未能解决你的问题,请参考以下文章

在 C# 中将 SQL 查询转换为 LINQ 方法语法

Linq C#方法语法,连接3个表

使用 LINQ 查询语法 EF Core C# 的左外连接

Linq语法

LINQ基础

linq简介