0

我是果园新手,我有一个新手问题。

我正在将现有的 mvc 应用程序转换为 Orchard,为了练习真实的东西,我正在尝试将 contoso 大学示例 MVC 应用程序转换为 Orchard 以学习基础知识。

我已经为它创建了一个模块,添加了菜单元素来访问应用程序,并且我还能够显示 Home\Index 操作的输出,以便我知道模块设置正确。

现在我正在尝试添加 Home\About 操作,它将显示从数据库查询生成的表。

这给了我以下错误:

服务器“DEV\SQLEXPRESS”上的 MSDTC 不可用。说明:执行当前 Web 请求期间发生未处理的异常。请查看堆栈跟踪以获取有关错误及其源自代码的位置的更多信息。

异常详细信息:System.Data.SqlClient.SqlException:服务器“DEV\SQLEXPRESS”上的 MSDTC 不可用。

源错误:

第 17 行:第 18 行:第 19 行:@foreach(模型中的变量项){ 第 20 行:第 21 行:

源文件:c:\Users\dev1\Documents\My Web Sites\Orchard CMS\Modules\ContosoUniversity\Views\Home\About.cshtml 行:19

源文件:c:\Users\dev1\Documents\My Web Sites\Orchard CMS\Modules\ContosoUniversity\Views\Home\About.cshtml 行:19

现在,经过一番谷歌搜索,我了解到这与抑制环境事务的需要有关。所以我添加一个using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Suppress))到我的家庭控制器:

public class HomeController : Controller
    {
        private SchoolContext db = new SchoolContext();
  [Themed]
        public ActionResult Index()
        {
            ViewBag.Message = "Welcome to Contoso University!";
            return View();
        }
  [Themed]
        public ActionResult About()
        {
            using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Suppress))

            {
                var query = "SELECT EnrollmentDate, COUNT(*) AS StudentCount "
                    + "FROM Person "
                    + "WHERE EnrollmentDate IS NOT NULL "
                    + "GROUP BY EnrollmentDate";
                var data = db.Database.SqlQuery(query);
                return View(data);
            }
        }

但是,它没有帮助。我已经阅读了其他地方来用这个来包围你的数据访问代码,但是当我使用实体框架时,我没有明确地打开任何数据连接,因此我不确定在哪里放置 using 语句。

4

3 回答 3

1

我认为这里的问题是查询的实际执行被延迟,实际上并没有发生在事务范围块内。如果您只是在 SQL 查询上调用 ToList(),那可能会解决它。这也是一种很好的做法,因为您不希望实际查询发生在视图中。您当前发送到视图的不是数据,而是查询。

于 2012-09-28T19:39:08.513 回答
0

什么类型的db.Database.SqlQuery()返回?您可以为您的视图和该视图使用的模型包含代码吗?

从这个错误消息看来,数据访问是从剃刀视图发生的。如果是这种情况,您可以通过foreach (var item in Model) { ...}using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Suppress)) {...}块包装来修复它。

您可能需要将正确的命名空间导入 razor 视图,以便 TransactionScope 的东西从那里工作。如果我没记错的话,我必须在 Orchard.Web\web.config<add assembly="System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />的块内添加。<system.web> <compilation> <assemblies>

于 2012-09-28T14:05:02.710 回答
0

感谢 Bertrand Le Roy 和 Giscard Biamby 将我推向了正确的方向。

我同意 Bertrand 的观点,即在控制器中添加 ToList 以强制执行查询是有意义的,但这并没有帮助。我必须做的是在视图中添加一个抑制子句,如下所示:

<table>
  <tr>
    <th>
      Enrollment Date
    </th>
    <th>
      Students
    </th>
  </tr>
  @using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Suppress))
  {
    foreach (var item in Model)
    {
    <tr>
      <td>
        @String.Format("{0:d}", item.EnrollmentDate)
      </td>
      <td>
        @item.StudentCount
      </td>
    </tr>
    }
  }
</table>

我还必须在视图的顶部添加一个 using 语句:

@model IEnumerable<ContosoUniversity.ViewModels.EnrollmentDateGroup>
@using System.Transactions 

最后,为了被允许使用引用,我必须在 web.config 中添加 System.Transactions 程序集:

<system.web>
    <compilation debug="true" targetFramework="4.0">
      <assemblies>
        <add assembly="System.Web.Abstractions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
        <add assembly="System.Web.Helpers, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
        <add assembly="System.Web.Routing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
        <add assembly="System.Web.Mvc, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
        <add assembly="System.Web.WebPages, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35" />
        <add assembly ="System.Transactions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/>

      </assemblies>
    </compilation>

现在我没有收到任何错误,但我也没有收到任何数据,但这是另一个问题。我相信这是朝着正确方向迈出的一步。

我希望有一种方法可以在更高的层次上做到这一点,以避免不得不改变我所有的观点,但至少我能够让它发挥作用。

于 2012-10-01T09:28:08.383 回答