传递DataContext对象作为'ref'参数有什么缺点吗?

6

在我的EF4项目中,我已经打开了DataContext文件本身以及DataContext生成的一些表/对象的部分类。但是,如果我将“Products”类作为部分类打开,则似乎没有直接从产品返回到生成它的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!
    }
}

但在部分类中,我希望能够直接查询数据库,并且我真的想初始化一个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);
     }
}

将我的DataContext对象作为ref参数传递给需要通过该连接访问数据库的任何部分类方法是否有缺点? 其中一个好处是,一旦将其作为ref传入,我可以从这些部分类中“AddObject()”新实体,并且一旦我的SaveChanges回调在asp.cs页面上被调用,所有更改(来自aspx和部分类方法)都会被执行。


DataContext是一个结构体还是类? - Adam Houldsworth
1
DataContext 是 LINQ to SQL 类。您确定您正在使用 Entity Framework 吗? - Steven
在VS 2010中使用Yup EF4。我所说的“DataContext”只是指由EF从我的数据模型(即EDMX文件)创建的大型对象。 - Graham
1个回答

10

传递ref变量是为了能够更改保存引用的变量。但由于您在GetPByRole方法中没有更改DataContext dbase引用,将其作为ref传递是无用的,只会让其他开发人员感到困惑。也许您误解了值类型和引用类型。引用类型(如DataContext)始终按引用传递,通过方法调用传递它不会创建对象本身的新副本,而只是引用的副本(它是一个32或64位的值)。

您在此混淆了职责。您的Product类是一个实体,但似乎您正在实现各种数据检索方法。这很快就会变成一团糟。为系统中的每个类分配单一职责。 Person类的职责是成为一个人。

换句话说,您正在尝试的更适合存储库类(甚至是周围的服务类)。例如,创建一个PersonRepository来保存这些方法。 PersonRepository将能够返回新的Person实例(实际上,存储库应该只是您的数据源和应用程序之间的接口,并且通常不会实现与业务相关的查询方法)。这样您就可以使您的实体不受数据上下文的影响(这是ADO.NET团队在开发Entity Framework时做出的非常谨慎的设计决策)。


你说的观点都很有道理。在“PersonRepository”类内,我需要初始化一个新的“DataContext”实例来进行检索,然后再将其销毁吗?我担心为单个页面请求创建和销毁太多的数据上下文对象,因此想要将其传递,但这种担忧是否有效呢? - Graham
2
就性能而言,我不会担心创建太多的“DataContext”。这对我来说从来不是问题。特别是当涉及到读取操作时。但由于原子性,您可能希望考虑每个请求使用较少的“DataContext”实例。我通常会将我的存储库包装在工作单元中,并让该工作单元控制“DataContext”。我将查询操作与业务交易(CUD操作)分开。查询类定义了诸如“GetPByRole”之类的方法,并在其下方使用工作单元和存储库:即http://bit.ly/gAoDnO - Steven

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接