将DataContext对象作为'ref'参数传递的任何缺点?

Gra*_*ham 5 .net linq linq-to-entities entity-framework-4

所以在我的EF4项目中,我打开了DataContext文件本身的部分类,以及DataContext生成的一些Table/Object.但是,如果我打开一个"产品"类作为部分,则没有(据我所知)从产品备份到产生它的DataContext类的直接链接.

public partial class Product 
{
    public DataContext GetContext() 
    {
        return this.DataContext; 
        // FAILS!!! No connection from 'this' to DataContext
        // makes sense because "Product" isn't REALLY derived from DataContext
        //...but still, I want this to work!
    }
}
Run Code Online (Sandbox Code Playgroud)

但是在部分产品类中,我确实希望能够直接查询数据库,我真的希望能够初始化一个DataContext实例并将其用于我的aspx.cs页面查询,以及执行的查询来自aspx.cs页面调用的部分类.

所以到目前为止我的解决方案是将DataContext的实例作为'ref'参数传递给我需要围绕数据库的部分类的方法.这是部分类:

public partial class Complaint
{
    public IEnumerable<Person> GetPByRole(InvestigationRole roleEnum, ref DataContext dbase)
    {
        var role = dbase.GetRole(roleEnum);
        return this.PeopleOnInvestigations
                   .Where(x => x.InvestigationRoleID == 1)
                   .Select(x => x.Person);
     }
}
Run Code Online (Sandbox Code Playgroud)

因此,将我的DataContext对象作为ref参数传递给需要通过此连接访问数据库的任何部分类方法是否存在缺点?其中一个优点是,一旦它作为ref传入,我可以从这些部分类中"添加对象()"新实体,并且一旦我的SaveChanges回调我的asp.cs页面,所有的更改(从aspx和部分类方法)得到执行.

Ste*_*ven 8

首先,传递ref变量用于能够更改保存引用的变量.但是,由于您没有更改方法中的DataContext dbase引用GetPByRole,因此将其作为a传递ref是无用的,甚至会使其他开发人员感到困惑.也许您误解了值类型和引用类型.引用类型(例如DataContext)总是通过引用传递,通过方法调用传递它不会创建对象本身的新副本,而只是引用的副本(它是32位或64位值).

其次,你在这里混合责任.您的Product类是一个实体,但您似乎在其上实现了所有类型的数据检索方法.这很快就会成为一大堆.为您的系统中的每个班级承担一项责任.Person班级的责任是成为一个人.

换句话说,您正在尝试的更适合存储库类(甚至是围绕该类的服务类).例如,创建一个PersonRepository包含这些方法的东西.在PersonRepository将能够返回新的Person实例(其实是仓库应该只是你的数据源和应用程序之间的接口,并通常不实施业务相关的查询方法).这样,您就可以使您的实体免于了解数据上下文(这是ADO.NET团队在开发实体框架时非常慎重的设计决策).

  • 我不担心创建太多的`DataContext',性能是什么.这对我来说永远不是问题.特别是当它涉及读取操作时.但是,由于atomicy,您可能需要考虑每个请求使用更少的`DataContext`实例.我通常做的是将我的存储库包装在一个工作单元中,让这个工作单元控制`DataContext`.我将查询操作与业务事务(CUD操作)分开.查询类定义类似`GetPByRole`的方法,并使用下面的工作单元和存储库:即http://bit.ly/gAoDnO (2认同)