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

私を正しい方向に押し進めてくれた Bertrand Le Roy と Giscard Biamby に感謝します。

コントローラーに ToList を追加してクエリの実行を強制することは理にかなっているという Bertrand の意見に同意しますが、それは役に立ちませんでした。私がしなければならなかったことは、次のようにビューに抑制句を追加することでした:

<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 に答える
0

どのタイプがdb.Database.SqlQuery()戻ってきますか?ビューとビューが使用しているモデルのコードを含めることができますか?

このエラー メッセージから、レーザー ビューからデータ アクセスが行われているように見えます。このような場合はforeach (var item in Model) { ...}using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Suppress)) {...}ブロックでラップすることで修正できます。

TransactionScope をそこから機能させるには、適切な名前空間を razor ビューにインポートする必要がある場合があります。私の記憶が正しければ、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 に答える