如果我 return 值并初始化它,为什么 Entity Framework 只调用存储过程?

Why does Entity Framework only call a stored procedure if I return the value and initialize it?

我正在使用 Entity Framework 6.1 调用已存在于 SQL 服务器中的存储过程。

var result = db.Database.SqlQuery<Log>("Scanning_Scan @Id, @SessionId, @Appname, @Barcode, @Username", _params);

目前为止效果很好。存储过程有一个 if 语句,它根据传递的 @Appname 参数选择不同的数据。

如果存储过程returns as

SELECT * FROM Scanning_Logs WHERE...

我可以使用

从结果中获取我的日志
foreach (item in result.ToList())
{
    do something with item.Barcode;
}

但是我实际上并不想使用这些数据。我可以忽略它。那是计划,直到我发现我从 if 语句调用的存储过程之一是 returning 作为一个不是 Log 的模型,本质上 returning 一些随机列并导致SQL 异常,因为它们不包含 Log.

中的标识列

为了解决这个问题,当我想调用那个特定的存储过程时,我 return 类型作为我创建的新 class。

class CartReturn
{
     public string CartNo;
     public string Barcode;
     public string Variation;
     public string Qty;
}

然后调用

var result = db.Database.SqlQuery<CartReturn>("Scanning_Scan @Id, @SessionId, @Appname, @Barcode, @Username", _params);
foreach (item in result.ToList())
{
    var barcode = item.Barcode;
}

真的很奇怪,条形码 return 显示为空白..但是当我检查存储过程时,它仍在被调用。伟大的!因为我不需要 return 任何东西,(我这样做只是为了在 returning 一个我不关心或不使用的数据类型时修复异常)我会清理代码并删除 foreach 语句,很高兴调用存储过程。

var result = db.Database.SqlQuery<CartReturn>("Scanning_Scan @Id, @SessionId, @Appname, @Barcode, @Username", _params);

这行不通。

我真的无法解释或理解为什么会出现这个问题,但确实如此。如果我去掉foreach循环,就不再调用存储过程了。

事实上,它似乎根本不是 for 循环。从测试来看,如果我不使用正在 returned 生成结果的日志,则根本不会调用存储过程。

作品:

var result = db.Database.SqlQuery<CartReturn>("Scanning_Scan @Id, @SessionId, @Appname, @Barcode, @Username", _params).ToList();
var i = result[0];
return;

不起作用:

var result = db.Database.SqlQuery<CartReturn>("Scanning_Scan @Id, @SessionId, @Appname, @Barcode, @Username", _params);
return;

我正式放弃...这是怎么回事?

发生的事情是,当您调用 .ToList() 时,您做了两件事:

  1. 将结果从 IQueryable 转换为 IEnumerable
  2. 实际获取数据

当您处于 IQueryable 中时,您的操作仍然会影响 EF 的操作,并且您的操作仍会影响它们的查询,但是一旦您可枚举,您就已经进行了提取。

EF陷阱前5,这个坑。

这里有一篇关于差异的好文章https://www.c-sharpcorner.com/UploadFile/a20beb/ienumerable-vs-iqueryable-in-linq/

让我们的头脑清醒过来非常重要,并因不接受怪异和参与社区而受到赞誉!实际上,在 .net 默认值和 SQL 默认值之间存在着许多奇怪的生活,并且创建查询时有或没有适当的垃圾数据处理明确到位,就像你描述的那样。