3

Entity Framework - Repository Pattern を使用しようとしています。(Asp.net C#、EF4)

各 DB テーブルのリポジトリを作成します。しかし、テーブルを結合すると、エラーが発生します

「指定された LINQ 式には、さまざまなコンテキストに関連付けられているクエリへの参照が含まれています。」

エラーメッセージを回避するために、次のようにすべてを1つのクラスに入れました:

public class WebOrderRepository
{
    private DbEntities context = new DbEntities(); //Web.config <add name="DBEntities" connectionString=" ...

    public IQueryable<WEBORDERHD> WebOrderHds
    {
        get { return context.WEBORDERHDs; }
    }

    public IQueryable<WEBORDERLN> WebOrderLns
    {
        get { return context.WEBORDERLNs; }
    }
}

私のコードを見直してください。

これは私のリポジトリクラスです。

public class Repository : IDisposable
{
    protected ShkAdsEntities context;
    private bool _disposed;

    public Repository()
    {
        context = new ShkAdsEntities();
    }

    public void Dispose() //If define this class as Static then, 'Dispose': cannot declare instance members in a static class

    {
        DisposeObject(true);
        GC.SuppressFinalize(this);
    }

    ~Repository()
    {
        DisposeObject(false);
    }

    private void DisposeObject(bool disposing)
    {
        if (_disposed)
        {
        return;
        }

        if(disposing){
        if (context != null)
        {
            context.Dispose();
        }
        _disposed = true;
        }
    }
}

public class WebOrderHdRepository : Repository
{
    public IQueryable<WEBORDERHD> WebOrderHds
    {
        get { return context.WEBORDERHDs; }
    }

    public void Create(WEBORDERHD obj)
    {
    }

    public void Delete(WEBORDERHD ojb)
    {
    }

    public void SubmitChanges()
    {
        context.SaveChanges();
    }
}

public class WebOrderLnRepository : Repository
{
    public IQueryable<WEBORDERLN> WebOrderLns
    {
        get { return context.WEBORDERLNs; }
    }

    public void Create(WEBORDERLN obj)
    {
    }

    public void Delete(WEBORDERLN ojb)
    {
    }

    public void SubmitChanges()
    {
        context.SaveChanges();
    }
}

これがテスト用のコントローラーです

[HttpGet]
public ActionResult repositoryTest()
{
    WebOrderHdRepository webOrderHdRepository = new WebOrderHdRepository();
    WebOrderLnRepository webOrderLnRepository = new WebOrderLnRepository();

    var result = (from x in webOrderHdRepository.WebOrderHds
          join u in webOrderLnRepository.WebOrderLns on x.OrderNo equals u.OrderNo
          select new {x.OrderNo}).SingleOrDefault();

    return Content(result.OrderNo);
}

コンテキストを静的として定義しようとしましたが、

protected static ShkAdsEntities context = null;
public Repository()
{
    if (context == null)
    {
    context = new ShkAdsEntities();
    }
}

その後、別のエラーが発生し、

Sequence contains more than one element
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.InvalidOperationException: Sequence contains more than one element

Source Error:


Line 116:        {
Line 117:            WebOrderHdRepository webOrderHdRepository = new WebOrderHdRepository();
Line 118:            WebOrderLnRepository webOrderLnRepository = new WebOrderLnRepository();  <== ERROR POINT
Line 119:
Line 120:            var result = (from x in webOrderHdRepository.WebOrderHds

Entity Framework-Repository パターンを多く検索します。しかし、ほとんどのことは非常に複雑です。だから私は上記のように簡単にしたい。

アドバイスお願いします〜

ありがとう!

[編集]

私はこれを試みます、

using(WebOrderHdRepository webOrderHdRepository = new WebOrderHdRepository())
using (WebOrderLnRepository webOrderLnRepository = new WebOrderLnRepository())
{
.
.

エラーが発生しますが、

The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.ObjectDisposedException: The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.

Source Error:


Line 114:        {
Line 115:            using(WebOrderHdRepository webOrderHdRepository = new WebOrderHdRepository())
Line 116:            using (WebOrderLnRepository webOrderLnRepository = new WebOrderLnRepository())
Line 117:            {
Line 118:

時間を2回処分しようとしていると思いますが、コードを修正する方法がわかりません...

どなたかご存知の方教えてください〜

ありがとう

4

2 に答える 2

3

このステートメントまで例外を追跡できます。

var result = (from x in webOrderHdRepository.WebOrderHds
      join u in webOrderLnRepository.WebOrderLns on x.OrderNo equals u.OrderNo
      select new {x.OrderNo}).SingleOrDefault();

障害が発生しましたSingleOrDefault- コレクションに複数の結果があります。MSDN のドキュメントを確認して、FirstOrDefault代わりに使用する必要があるかどうかを判断してください。

特にSingleOrDefault動作に関して、MSDN は次のように説明しています (強調を追加)。

シーケンスの唯一の要素を返します。シーケンスが空の場合はデフォルト値を返します。シーケンスに複数の要素がある場合、このメソッドは例外をスローします

DbContext に関しては、別々のリポジトリを持つことができるはずです。各リポジトリが同じコンテキスト オブジェクトを使用していることを確認してください。(元の実装を見ずに) 各リポジトリが独自のコンテキスト オブジェクトをインスタンス化したと推測します。現在の実装に特定の問題は見られませんが、次のようなものを提案する人もいます ( untested ):

  public ActionResult repositoryTest() {
     ActionResult actionRes = default(ActionResult);

     using (ShkAdsEntities context = new ShkAdsEntities())
     using (WebOrderHdRepository webOrderHdRepository = new WebOrderHdRepository(context))
     using (WebOrderLnRepository webOrderLnRepository = new WebOrderLnRepository(context)) {

        var result = (from x in webOrderHdRepository.WebOrderHds
                      join u in webOrderLnRepository.WebOrderLns on x.OrderNo equals u.OrderNo
                      select new { x.OrderNo }).SingleOrDefault();

        actionRes = Content(result.OrderNo);
     }

     return actionRes;
  }

更新:
上記で示したリポジトリ テストを試す場合は、リファクタリングを行う必要があります。クラスの現在の状態では機能しません。これは、投稿する必要がある別の質問になります。上記のスニペットは、クエリどのように見えるかの例にすぎません。@ Florim Maxhuni が示唆するように、依存性注入 (DI) は実際に進むべき道です。単に要件と時間の制約に依存します。DbContext に問題がある場合、それは別の質問であり、新しいスレッドに投稿する必要があります。:)

于 2012-07-14T15:15:06.140 に答える
1

各リポジトリが独自のコンテキストを作成するという強制は、まったく間違っています。代わりに、コンテキストをリポジトリに注入する必要があります。ここでは、コンストラクター注入がうまく機能します。

このようにして、コンテキストを完全に制御し、リポジトリ間で共有できます。たとえば、Web アプリでは、単一の要求の有効期間を持つコンテキストを持つことができます。

于 2012-07-14T17:34:41.397 に答える