在 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)
由于 _qStatus 为 Empty,不应进行下一次检查。
【问题讨论】:
最可能的原因是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) 时发生异常的主要内容,如果未能解决你的问题,请参考以下文章