0

私の現在のアプリは、EF 4.1 Code First と Oracle バックエンドで .NET MVC3 を使用しています。複数の画像を表示する View がある 1 つのシナリオを除いて、すべてが事実上常に正常に機能します。すべての画像が正常に読み込まれる場合もあれば、読み込みに失敗する場合もあり、「接続が閉じられていませんでした」または「接続を開く必要があります」という 2 つのエラー メッセージのいずれかが表示されます。イメージは、サーバーのファイル システムではなく、BLOB としてデータベースに格納されます。ドキュメント (画像) のコレクションを含むビュー モデルがあり、EditorTemplate を使用してコレクションをビューにレンダリングします。レンダリングされたコードは、Controller アクションを呼び出して、コレクション内の各画像を取得します。コレクションをレンダリングする Razor コードは次のとおりです。

親ビュー:

<div  id="carousel1" class="data-carousel">
    @Html.EditorFor(x => x.Documents)
</div>

エディター テンプレート:

<div>
    <img style="border: solid; border-color: lightgrey; border-width: thin" src="@Url.Action("GetImage", "Product", new {docId = Model.DocumentID, width = 250, height = 250})" alt=""/>           
</div>

このコードはブラウザに書き込まれます

<img style="border: solid; border-color: lightgrey; border-width: thin" src="http://localhost:9613/Product/GetImage?docId=1&width=250&height=250" alt=""/>
<img style="border: solid; border-color: lightgrey; border-width: thin" src="http://localhost:9613/Product/GetImage?docId=2&width=250&height=250" alt=""/>
<img style="border: solid; border-color: lightgrey; border-width: thin" src="http://localhost:9613/Product/GetImage?docId=3&width=250&height=250" alt=""/>
<img style="border: solid; border-color: lightgrey; border-width: thin" src="http://localhost:9613/Product/GetImage?docId=4&width=250&height=250" alt=""/>

ご覧のとおり、これにより、id を含むいくつかのパラメーターを、画像をバイト配列として返すアクション メソッドに渡すリンクが作成されます。

public void GetImage(int docId, int width, int height)
{
    // Load image from database
    var doc = productRepository.Documents.SingleOrDefault(f => f.DocumentID == docId);
    var image = doc.FileContent;

    new WebImage(image)
   .Resize(width, height, true, true)
   .Crop(1, 1)
   .Write();
}

何が起こっているのかは、コントローラーアクションが各イメージ (潜在的に最大 10) に対して呼び出されており、次の要求が来る前にデータベース接続が閉じられていないことだと確信しています。 「using」ステートメントで Context の新しいインスタンスを使用して、これが改善されるかどうかを確認しますが、改善しませんでした。それで、私にできることはありますか?おそらく新しい非同期を見る必要がありますか、それともビューで複数の画像を取得するために使用できる他のパターンがありますか?

ティア

編集:

アプリケーションは IIS7 でホストされ、クラシック パイプライン モードの独自のアプリケーション プールがあります。StructureMap を IoC コンテナーとして使用するため、これによって DbContext の作成と有効期間が制御されます。Controller がインスタンス化されると、インスタンス化が行われます。

SM セットアップ:

public static class StructuremapMvc 
{
    public static void Start() 
    {
        var container = (IContainer)IoC.Initialize();
        DependencyResolver.SetResolver(new SmDependencyResolver(container));
    }
}

public static IContainer Initialize() 
{
    ObjectFactory.Initialize(x =>
    {
        x.Scan(scan =>
        {
            scan.TheCallingAssembly();
            scan.WithDefaultConventions();
        });
        x.For<IProductRepository>().Use<ProductRepository>();
        x.For<IProductContext>().Use<ProductContext>();
    });

    return ObjectFactory.Container;
}

コントローラ:

public class ProductController : Controller
{
    private readonly IProductRepository productRepository;

    public ProductController(IProductRepository productRepository)
    {
        this.productRepository = productRepository;
    }

    public void GetImage(int docId, int width, int height)
    {
        // Load image from database
        var doc = productRepository.Documents.SingleOrDefault(f => f.DocumentID == docId);
        var image = doc.FileContent;

        new WebImage(image)
       .Resize(width, height, true, true)
       .Crop(1, 1)
       .Write();
    }

    // etc.
}

リポジトリ:

public class ProductRepository : IProductRepository
{
    private readonly IProductContext productContext;

    public ProductRepository(IProductContext productContext)
    {
        productContext = productContext;
    }

    public IQueryable<Document> Documents
    {
        get { return productContext.Documents; }
    }

    // etc.
}

環境:

public class ProductContext : DbContext, IProductContext
{
    // DbSets
    public IDbSet<Document> Documents { get; set; }

    public void SetModified(object entity)
    {
        Entry(entity).State = EntityState.Modified;
    }   

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        // etc.
    }

    // etc. 
}
4

0 に答える 0