我是一个果园新手,我有一个新手问题。
我正在将现有的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语句
答案 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>
现在我没有收到任何错误,但我也没有得到任何数据,但这是另一个问题。我相信这是朝着正确方向迈出的一步。
我希望有一种方法可以在更高的层次上做到这一点,以避免改变我的所有观点,但至少我能够使它发挥作用。