Asp.net mvc ASP.NET MVC应用程序中Linq到Sql的DataContext设计问题和注意事项

Asp.net mvc ASP.NET MVC应用程序中Linq到Sql的DataContext设计问题和注意事项,asp.net-mvc,linq-to-sql,architecture,datacontext,Asp.net Mvc,Linq To Sql,Architecture,Datacontext,在ASP.NETMVC应用程序中使用LINQtoSQL时,我使用“每个原子操作的单数据上下文”方法 到目前为止,我一直在使用单例datacontext,我知道它有很多问题,所以我重构了代码,在每个原子操作中使用单例datacontext 控制器操作的示例如下(重构并没有改变这一点): public ActionResult List() { List requests=this.repository.AllRequests(); 返回视图(请求); } 存储库的类型为IRepository。我

在ASP.NETMVC应用程序中使用LINQtoSQL时,我使用“每个原子操作的单数据上下文”方法

到目前为止,我一直在使用单例datacontext,我知道它有很多问题,所以我重构了代码,在每个原子操作中使用单例datacontext

控制器操作的示例如下(重构并没有改变这一点):

public ActionResult List()
{
List requests=this.repository.AllRequests();
返回视图(请求);
}
存储库的类型为IRepository。我希望保持这种抽象,以便能够切换到不同的数据层(根据我最近使用Linq到Sql的经验,这种情况很快就会发生:)

LinqRepository实现AllRequests()方法,如下所示:

    public List<Request> AllRequests()
    {
        using (DataModelDataContext connection = GetContext())
        {
            return connection.Requests.ToList();
        }
    }
    public List<Request> AllRequests()
    {
        DataModelDataContext connection = GetContext();
        return connection.Requests.ToList();
    }
public列出所有请求()
{
使用(DataModelDataContext连接=GetContext())
{
返回connection.Requests.ToList();
}
}
(仅供参考,以前DataContext实例是LinqRepository的一个字段,LinqRepository作为单个静态实例持有)

DataContext在方法返回之前被释放

视图代码现在在访问延迟属性时抛出ObjectDisposed异常:

            <%= Html.Encode(request.Branch.Name) %> //throws
//抛出
我了解到可能不需要处理DataContext(此处)

当我不处理DataContext(删除using)时,就没有ObjectDisposedException

i、 e:我改变了方法如下:

    public List<Request> AllRequests()
    {
        using (DataModelDataContext connection = GetContext())
        {
            return connection.Requests.ToList();
        }
    }
    public List<Request> AllRequests()
    {
        DataModelDataContext connection = GetContext();
        return connection.Requests.ToList();
    }
public列出所有请求()
{
DataModelDataContext连接=GetContext();
返回connection.Requests.ToList();
}
但我想知道,在这个场景中不处理DataContext实例会有什么影响

我知道我应该在处理DataContext之前读取实体实例中的所有数据(包括延迟属性),但我不想引入另一个抽象(另一个请求类,将所有属性复制到它)

我的问题是:

实体对象是否持有对其父DataContext的强引用,从而防止对其进行GC调用?(我想是的,朱特想100%确定)

在需要保留数据层抽象的情况下,您能否就使用Linq to Sql的推荐方法提供建议?(包括部分属性更新)


是否有一个开源项目使用ASP.NET MVC中实现Linq到Sql的存储库抽象?

我的解决方案是让存储库实现IDisposable。然后,我将在OnActionExecuting中的构造函数中的控制器中将存储库实例化为实例变量。然后,我将在OnResultExecuted中处理存储库。当您到达OnResultExecuted时,结果已经呈现,并且所需的任何数据都已消耗。存储库将类似地在其构造函数中实例化DataContext,并在释放时将其释放。

我的解决方案是让存储库实现IDisposable。然后,我将在OnActionExecuting中的构造函数中的控制器中将存储库实例化为实例变量。然后,我将在OnResultExecuted中处理存储库。当您到达OnResultExecuted时,结果已经呈现,并且所需的任何数据都已消耗。存储库将类似地实例化它的构造函数中的DATACONTEX,并在处理它时处理它。

首先,让我们考虑一下发生了什么。

你是:

  • 打开数据上下文
  • 获取一些数据
  • 关闭数据上下文
  • 正在尝试读取从数据上下文返回的数据
这一情景是为工作而设计的。然而,要使其始终有效,需要加载所有数据

默认情况下,LinqToSql将延迟(aka defer)加载它认为合适的内容。在本例中,似乎正在延迟加载Request.Branch或至少Request.Branch.Name。要正确地延迟加载某些内容,数据上下文必须仍然存在,而在您的场景中,它不再存在

以下是一些让您的场景正常工作的选项:

备选案文1:

在处理数据上下文之前,以某种方式“强制”加载Request.Branch.Name。这在LinqToSql中是可能的,尽管不一定像您希望的那样容易或方便。这应该允许您继续使用“每个原子操作一个数据上下文”模式,尽管这种方法还有其他缺点。数据上下文支持有关更改跟踪、缓存和其他场景的重要功能,虽然您希望尽快处置数据上下文,但保持数据上下文的开放性有着显著的优势,因此,在保持数据上下文的开放时间比当前保持数据上下文的开放时间更长方面,您应该持开放的态度。实现选项1的一种方法是使用您在说“另一个请求类”时提到的方法,但在本场景中,这可能会有点过分

备选案文2:

在用户开始其操作时打开数据上下文,并在用户结束其操作时处置它。这就是所谓的模式。这允许延迟加载正常工作,并为您提供更改跟踪和其他优秀的ORM特性。它的实现可能更具挑战性,但它最有可能在大多数情况下工作

Tvanfosson的答案介于选项1和选项2之间,有很多折衷的机会来解决您的问题。所有的ORM都有一条学习曲线,LinqToSql也不例外。大多数ORM都有一些类似于LinqToSql的数据上下文的东西,从LinqToSql中切换并不能免除您必须理解数据上下文是如何工作的以及为什么工作的

你永远不想开一家数据公司