【问题标题】:MVC3 Data Context Best PracticeMVC3 数据上下文最佳实践
【发布时间】:2011-12-18 22:22:22
【问题描述】:

这是我在控制器中执行的操作。在此控制器内部创建和处理数据库连接(即 PhotoGalleryContext - 它是与 MySql 数据库的连接)而不是通过在模型的数据访问层中完成此操作来进行抽象是否被认为是不好的做法。 cs课?

    // GET: /Admin/GetPhoto/id
    public ActionResult GetPhoto(int id)
    {
        PhotoGalleryContext db = new PhotoGalleryContext();

        Models.PhotoGallery.Photo photo = new Models.PhotoGallery.Photo();
        photo = db.Photos.Where(p => p.PhotoId == id).Single();

        string filePath = photo.FileLocation;

        db.Dispose();    

        byte[] byteArray;
        try
        {
            byteArray = System.IO.File.ReadAllBytes(filePath);
            return File(byteArray, "image/jpg");
        }
        catch (Exception)
        {
            //throw;
        }
        return null;
    }

【问题讨论】:

  • 你在哪里处理 db (PhotoGalleryContext)?不在这个例子中?
  • 复制粘贴错误,已编辑以显示 dispose

标签: database asp.net-mvc-3 controller repository datacontext


【解决方案1】:

在决定这个时,您可能会考虑您的应用程序的大小。我想说分离模型是一种最佳实践,但对于较小的应用程序,也许您应该将 PhotoGalleryContext 包装在 using 块中:

using(PhotoGalleryContext db = new PhotoGalleryContext())
{

    Models.PhotoGallery.Photo photo = new Models.PhotoGallery.Photo();
    photo = db.Photos.Where(p => p.PhotoId == id).Single();

    string filePath = photo.FileLocation;
    byte[] byteArray;
    try
    {
        byteArray = System.IO.File.ReadAllBytes(filePath);
        return File(byteArray, "image/jpg");
    }
    catch (Exception)
    {
        //throw;
    }
    return null;
}

【讨论】:

  • 如果我要将它分离到模型中,我是否仍然只是在每次像这样的控制器内部实例化 PhotoGalleryManager 类,然后在最后处理它?如果我的管理器包含许多不同的操作,那么为这样的轻量级加载整个管理器类会很慢吗?
  • using() 比调用 .dispose() 好吗?
  • using() 在大括号末尾调用 Dispose(),imo 使代码一目了然(只要您嵌套格式化代码)。
【解决方案2】:

同意 David,这取决于您的应用程序的大小。

但是,我建议使用依赖注入来为您管理连接。

使用StructureMap 之类的东西,你可以有这样的东西:

For<PhotoGalleryContext>()
   .HybridHttpOrThreadLocalScoped
   .Use<PhotoGalleryContext>();

翻译为:

当有东西请求 PhotoGalleryContext 时,给它一个新的 PhotoGalleryContext,它是 HTTP-scoped(在请求开始时创建,在结束)。

这样,StructureMap 会自动为您打开/关闭连接。

那么你的控制器可以如下所示:

private readonly PhotoGalleryContext _db;
public AdminController(PhotoGalleryContext db)
{
   _db = db;
}

在您的操作方法中,_db 将准备好为您服务。

几行代码可以在您的应用程序中节省大量重复的 using 语句。

【讨论】:

  • 如果我返回的模型仍在使用数据库上下文的浅拷贝,是否会阻止调用 dispose?
  • @TravisJ - 不,因为视图的呈现仍然是当前 HTTP 请求的一部分,然而,这是不好的做法。您的视图不应该知道/关心任何数据库连接。为什么模型会使用 ctx 的浅拷贝?
  • 在创建对象以返回和复制 db 对象的部分内容时,会在上下文中保留浅拷贝。我制作了硬拷贝以确保在处理 db 对象时数据仍在我的副本中,但是我不确定如果不自动进行垃圾收集是否会使该解决方案保持连接。
  • 我希望避免使用大量开销,虽然代码可能更具可读性,但 StructureMap 似乎会增加总请求时间。 HybridHttpOrThreadLocalScoped 很重要。
  • @TravisJ - 我想你现在挑剔的。我看不出 StructureMap 会如何给请求时间增加太多开销。是的,使用会减少连接时间。但是如果你担心性能,你应该关注核心领域,如数据库查询、HTTP 请求等。过早的优化是死亡。我仍然不明白为什么你需要做一个浅拷贝。您应该将您的数据库对象映射到 ViewModel,这些 ViewModel 会呈现给 View。这样您就不必担心将数据保留在原始对象中。
猜你喜欢
  • 2015-12-14
  • 1970-01-01
  • 1970-01-01
  • 2012-09-25
  • 2021-12-30
  • 2014-08-30
  • 1970-01-01
  • 2010-09-05
  • 1970-01-01
相关资源
最近更新 更多