0

我当前的应用程序使用带有 EF 4.1 Code First 和 Oracle 后端的 .NET MVC3。除了在一个场景中,我们有一个显示多个图像的视图,几乎所有时间都运行良好。有时所有图像都加载正常,有时其中一些无法加载,我收到 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 在内的一些参数传递给 action 方法,该方法将图像作为字节数组返回:

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 个)都调用了 Controller 操作,并且在下一个请求到来之前没有关闭 db 连接。我尝试在存储库上创建一个方法来创建在“使用”语句中创建一个新的上下文实例,看看这是否会改善事情,但事实并非如此。那么有什么我可以做的吗?我应该查看新的异步,还是可以使用其他模式来检索视图中的多个图像?

TIA

编辑:

该应用程序托管在 IIS7 中,并在经典管道模式下拥有自己的应用程序池。我使用 StructureMap 作为 IoC 容器,因此它控制 DbContext 的创建和生命周期。实例化发生在控制器被实例化时:

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