-1

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

数据库表中有两列。并且“状态”列映射到具有枚举类型的程序:1(免费),2(贷款)。

。数据库表模式如下。 在此处输入图像描述

。定义表类

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,不应该进行下一次检查。

4

2 回答 2

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,并且可以避免不必要的转换。

于 2021-08-16T16:35:02.873 回答
0

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

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

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

参考:

为什么这种短路在 linq to sql 查询中不起作用?

为什么 lambda 中的这种短路不起作用?

于 2021-08-17T03:06:46.840 回答