1

我刚刚开始学习实体框架(从 5.0 开始)并遇到了一些问题。在观看了 Pluralsight 上的一些视频后,我决定发挥创意,创建了一个继承自 DbContext 的抽象基类,并公开了一个“DataContext”属性,该属性是一个泛型类型的 DbSet。像这样的东西:

public abstract class BaseDataContext<E> : DbContext
     where E : CustomEntity
{
      public DbSet<E> DataContext {get;set;}

      public BaseDataContext()
      {
           Database.SetInitializer<BaseDataContext<E>>(null);
      }
 }

在我开始处理彼此有关系的实体(父/子)之前,这似乎工作得很好。发生的事情是,当我尝试通过继承 BaseDataContext 的数据类向数据库添加一个新的子实体时,而不是仅仅附加引用(意思是,带着孩子说“你的父键是 123”),它创建了另一个使用父项的新键记录,所有其他字段重复,并使此新记录成为子项的父项。我尝试只设置我孩子的 key 属性(取消与数据一起公开的属性),但这并没有改变任何东西。我在 SO (这里) 上发现了一个线程,它说像我试图做的那样做多个数据上下文并不是一个好主意,并且似乎准确地解释了正在发生的事情。

我的问题是,随着 EF 似乎越来越受欢迎,这是常用的方法吗?要创建一个单一的数据上下文,然后随处传递构造函数?还是有更简单的更常见的方法?如果事情进入后台线程,这尤其适用,因为在那里传递上下文可能会变得困难。

提前致谢!

4

1 回答 1

2

当您按预期使用时,您可以像任何工具一样充分利用 EF。所以你问很好。实体框架,尤其是代码优先,都是关于持久性无知的(例如在这里解释)。我不知道您的评论“就像您在 EF/L2S 之前所做的那样”指的是什么,但听起来像是active record。那不是要走的路。

上下文负责物化存储中的实体,跟踪更改并将更改保存到数据库。更详细地说:上下文管理工作单元(跟踪更改),它的DbSet成员充当基本存储库(实现和保存)。实体类本身对此一无所知。(附带说明:在ObjectContextAPI 中它们确实如此,但它们可以被编码为对持久性无知)。

现在关于“多个上下文”。您提到的问题是关于同一上下文类型的多个上下文实例。您的问题是关于多种上下文类型(并且必然是多个实例)。让我们整理一下:

  • 上下文类型的数量:上下文类型的数量通常非常有限,通常甚至只有一种。为什么?因为覆盖大部分数据库的上下文能够检索和保存许多不同的对象图。所以它服务于大量的用例,现在和未来,稳定和变化,但它本身是稳定的。它仅在数据库更改时更改,而不是在应用程序更改时更改。(我应该说,虽然每个用例都有一种上下文类型的倡导者,但我发现它们有大量共同的类是不可避免的,非常令人困惑)。
  • 上下文实例的数量:这个问题不能用几句话完全涵盖,但应该记住,上下文 (1) 缓存数据和 (2) 跟踪和存储更改。因此,长期存在的上下文很快就会包含陈旧的数据,并且它们会随着变化的发生而增长。共识是保持上下文“短暂”存在,但什么是短暂的?它可以是每个 http 请求一个实例,每个服务调用一个实例,每个(业务)事务一个实例,但也可以是 MDI 接口中的每个表单一个实例,每个线程一个实例......请参阅此处关于 Linq-to-Sql 上下文的有用讨论, EF 上下文(或 NHibernate 会话)也是如此。有一点很清楚:不要使用一个静态上下文,因为有些人很想这样做。

因此,尽可能发挥创造力,尽可能多地进行实验。按照预期使用 EF,并获得很多乐趣!

于 2012-11-03T22:37:58.150 回答