【问题标题】:open DataReader error on Azure SQL but not SQL Server 2014在 Azure SQL 但不是 SQL Server 2014 上打开 DataReader 错误
【发布时间】:2015-06-21 10:00:50
【问题描述】:

我在这方面找到了一些帖子,但似乎找不到与我的代码相关的帖子。

以下行突出显示错误:

Line 74:         <td>
Line 75:             @Html.DisplayFor(modelItem => item.Equipment.ModelName)
Line 76:         </td>

呈现数据的视图部分如下所示:

@foreach (var item in Model) {
    <tr>
        <td>
            @Html.DisplayFor(modelItem => item.Location)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Position)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Description)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.SerialNo)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.InstallDate)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.ServiceFrequency) Months
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.NextServiceDate)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Equipment.ModelName)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Owner.OwnerName)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.ServiceCompany.CompanyName)
        </td>
        <td>
            @Html.DisplayFor(modelItem => item.Site.SiteName)
        </td>

        <td>
            @Html.ActionLink("Edit", "Edit", new { id=item.AssetID })
            @Html.ActionLink("Details", "Details", new { id=item.AssetID })
            @Html.ActionLink("Delete", "Delete", new { id=item.AssetID })
        </td>
    </tr>

控制器如下所示:

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);
}

我的理解是我已经尝试连接到数据库两次,但是我看不到在哪里,而且我的笔记本电脑上也没有出现这个错误。我觉得它可能是 Azure SQL 数据库中不可用的东西,但在 SQL Server 2014 中很好。

有什么想法吗?

更新::::

我已通过将 MultipleActiveResultSets=true 添加到连接字符串来停止该问题,但是我不确定这是否掩盖了需要解决的问题或可能引入了其他问题。

【问题讨论】:

    标签: asp.net asp.net-mvc azure azure-sql-database


    【解决方案1】:

    添加MultipleActiveResultSets=true 很好。

    默认情况下我总是将其设置为 true - 它通常更安全,尤其是在您使用任何 3rd 方库时。

    但是,在这种特殊情况下导致这种情况的原因是您的代码中有一个 SELECT N+1 问题(您为每条记录返回 SQL 以检索另一位数据)。

    例如,您渲染 item.Equipment.ModelName 会导致另一个往返服务器来获取它(假设它们是虚拟属性)。因此,您已经有一个打开的连接,因此您可以遍历结果集,并且您需要在同一连接上运行另一个查询以获取 Equipment 实体。 当您迭代结果集时,任何 ORM 和虚拟属性都可以很容易地发生这种情况。您通常可以通过告诉 ORM 预取您需要的属性来解决它,或者更好的是,通过在查询中进行投影,以便 SQL 为您提供您需要的所有数据,仅此而已。更好的性能。在你的情况下,而不是select a,做类似的事情

    select new {
       a.Location,
       a.Position
       ....
       EquipmentName = a.Equipment.ModelName
       ....
     }
    

    现在,您可以将其作为动态传递给您的视图(我认为 - 不确定),但您可能希望创建一个具有相关属性的具体类(R# 会这样做为您)以便更轻松地将其发送到视图。

    检测这种情况的最简单方法是在 SQL Server 的本地实例上使用 SQL Server Profiler 来准确查看哪些查询/查询发送到 SQL Server。

    【讨论】:

    • 感谢您的提示。我去看看。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-14
    • 1970-01-01
    • 2018-11-22
    • 2015-06-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多