将 DataContext 对象作为“ref”传递的任何缺点;范围?
因此,在我的 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 参数传递给任何需要通过此连接访问数据库的分部类方法是否有缺点? 优点之一是,一旦它作为引用传入,我可以从这些分部类中“AddObject()”新实体,一旦我的 asp.cs 页面上的 SaveChanges 回调完成,所有更改(来自 aspx 和分部类)方法)被执行。
So in my EF4 project I have opened up the partial classes of both the DataContext file itself, as well as a couple of the Table/Object generated by the DataContext. However, if I open up a "Products" class as a partial, there isn't (as far as I can tell) a direct link from product back up to the DataContext class that spawned it.
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!
}
}
But inside by partial product class, I sure would like to be able to query the database directly, and I really like to be able to initialize just one instance of DataContext and use it for my aspx.cs page queries, as well as queries executed from the partial classes that are called from the aspx.cs page.
So my solution so far is to pass in the instance of DataContext as a 'ref' parameter to the methods of my partial class that need to poke around the database. Here's the partial class:
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);
}
}
So is there a downside to passing around my DataContext object as a ref parameter to any partial class methods that need access to the database through this connection? One of the upsides is that once its passed in as a ref, I can "AddObject()" new entities to it from within these partial classes, and once my SaveChanges call back on my asp.cs page is made, ALL the changes (from the aspx and from the partial class methods) get executed.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
传递
ref
变量用于能够更改保存引用的变量。但由于您没有更改GetPByRole
方法中的DataContext dbase
引用,因此将其作为ref
传递是没有用的,只会让其他开发人员感到困惑。也许您误解了值类型和引用类型。引用类型(例如 DataContext)始终通过引用传递,通过方法调用传递它不会创建对象本身的新副本,而只是引用的副本(可以是 32 位或 64 位)价值)。你在这里混合了责任。您的
Product
类是一个实体,但您似乎正在其上实现各种数据检索方法。这很快就会变得一团糟。为系统中的每个类赋予单一职责。Person
类的职责是成为一个人。换句话说,您想要做的事情更适合存储库类(甚至是围绕它的服务类)。例如,创建一个包含这些方法的
PersonRepository
。PersonRepository
将能够返回新的Person
实例(事实上,存储库应该只是数据源和应用程序之间的接口,通常不会实现与业务相关的查询方法)。通过这种方式,您的实体无需了解数据上下文(这是 ADO.NET 团队在开发实体框架时经过深思熟虑的设计决策)。Passing a
ref
variable is used to be able to change variable that holds the reference. But since you are not changing theDataContext dbase
reference in yourGetPByRole
method, passing it as aref
is useless and would only confuse other developers. Perhaps you misunderstand value types and reference types. Reference types (such asDataContext
) are always passed by reference, passing it around through method calls will not make new copies of the object itself, merely copies of the reference (which is either a 32 or 64 bits value).You are mixing responsibilities here. Your
Product
class is an entity, but you seem to be implementing all kind of data retrieval methods on it. This will become a big mess very soon. Give every class in your system a single responsibility. The responsibility of thePerson
class is to be a person.In other words, what you are trying to to is much more suited for repository classes (or even service classes around that). For instance, create a
PersonRepository
that holds these methods. ThePersonRepository
will be able to return newPerson
instances (in fact a repository should just be the interface between your data source and your application and would normally not implement business related query methods). This way you keep your entities free from knowing the data context (which is a very deliberate design decision of the ADO.NET team while developing Entity Framework).