将MVC应用程序转换为Orchard CMS

时间:2012-09-28 12:32:43

标签: orchardcms

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

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

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

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

这给了我以下错误:

  

服务器'DEV \ SQLEXPRESS'上的MSDTC不可用。描述:一个   在执行当前Web期间发生了未处理的异常   请求。请查看堆栈跟踪以获取有关的更多信息   错误以及它在代码中的起源。

     

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

     

来源错误:

     

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

     

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

     

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

现在,经过一些谷歌搜索,我知道这与抑制环境事务的需要有关。所以我将使用(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语句

3 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分: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>

答案 2 :(得分:0)

感谢Bertrand Le Roy和Giscard Biamby让我朝着正确的方向前进。

我同意Bertrand认为在控制器中添加ToList以强制执行查询是有意义的,但这没有用。我必须做的是在视图中添加一个suppress子句,如下所示:

<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>

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

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