Asp.net Azure SQL而非SQL Server 2014上的open DataReader错误
我找到了一些关于这方面的帖子,但似乎找不到与我的代码相关的帖子 下一行高亮显示错误:Asp.net Azure SQL而非SQL Server 2014上的open DataReader错误,asp.net,asp.net-mvc,azure,azure-sql-database,Asp.net,Asp.net Mvc,Azure,Azure Sql Database,我找到了一些关于这方面的帖子,但似乎找不到与我的代码相关的帖子 下一行高亮显示错误: Line 74: <td> Line 75: @Html.DisplayFor(modelItem => item.Equipment.ModelName) Line 76: </td> 据我所知,我曾两次尝试连接到数据库,但我看不到在哪里,而且我的笔记本电脑上也没有出现此错误。我觉得它可能是Azure SQL数据库中不可用
Line 74: <td>
Line 75: @Html.DisplayFor(modelItem => item.Equipment.ModelName)
Line 76: </td>
据我所知,我曾两次尝试连接到数据库,但我看不到在哪里,而且我的笔记本电脑上也没有出现此错误。我觉得它可能是Azure SQL数据库中不可用的东西,在SQL Server 2014中也可以
有什么想法吗
更新:::
我已经通过向连接字符串添加MultipleActiveResultSets=true停止了该问题,但是我不确定这是否掩盖了需要解决的问题,或者可能引入了其他问题 添加
MultipleActiveResultSets=true
就可以了
我总是在默认情况下将其设置为true-这通常更安全,尤其是如果您使用任何第三方库
然而,在这种特殊情况下,造成这种情况的原因是代码中存在SELECT N+1问题(在代码中,对于每条记录返回SQL以检索另一位数据)
例如,您呈现item.Equipment.ModelName
,这会导致到服务器的另一次往返获得该属性(假设它们是虚拟属性)。因此,您已经有一个打开的连接,因此您可以迭代结果集,并且需要在同一连接上运行另一个查询以获取设备实体。
当您迭代结果集时,任何ORM和虚拟属性都很容易发生这种情况。通常,您可以通过告诉ORM预取所需的属性来解决此问题,或者,更好的方法是,在查询中进行投影,以便SQL为您提供所需的所有数据。性能更好。在您的情况下,不要选择一个,而是执行以下操作
select new {
a.Location,
a.Position
....
EquipmentName = a.Equipment.ModelName
....
}
现在,您可以将其作为动态(我想-不确定)传递给视图,但您可能希望创建一个具有相关属性的具体类(R#将为您这样做),以便更轻松地将其发送给视图
检测此问题的最简单方法是在SQL Server的本地实例上使用SQL Server探查器,以准确地查看将哪些查询发送到SQL Server 谢谢你的提示。我来看看。
public ActionResult Index()
{
var userId = User.Identity.GetUserId();
var asset = from a in db.Assets
join o in db.Owners on a.OwnerID equals o.OwnerID into oa
from asst in oa.DefaultIfEmpty()
join s in db.ServiceCompanies on a.ServiceCompanyID equals s.ServiceCompanyID into sa
from service in sa.DefaultIfEmpty()
where asst.RegUserID == userId || service.RegUserID == userId
select a;
return View(asset);
}
select new {
a.Location,
a.Position
....
EquipmentName = a.Equipment.ModelName
....
}