27

我见过程序员在代码中创建实体上下文时采用的两种不同方式。

第一个是这样的,你可以在 MSDN 代码示例中找到它:

public void DoSomething() {
     using (TaxableEducationEntities context = new TaxableEducationEntities()) {
          // business logic and whatever else
     }
}

第二个是将上下文创建为封装业务逻辑的某个类中的私有属性。所以你会有类似的东西:

public class Education_LINQ {

        private TaxableEducationEntities context = new TaxableEducationEntities();

        public void DoSomething() {
            var result = from a in context.luAction
                         select a;

            // business logic and whatever else
        }
}

哪种方式更有效?

假设您有两种方法,一种称为 DoSomething1(),另一种称为 DoSomething2(),并且这两种方法都包含 using 语句来打开上下文并对其执行任何操作。如果您要一个接一个地调用一个方法,是否会产生任何多余的开销,因为本质上这两种方法都会创建上下文,然后在完成后将其清除?与仅在实例化类对象时创建一个私有属性相反,然后在对象超出范围时依次清理?

4

2 回答 2

41

每次创建一个新的 ObjectContext 确实涉及“一些”开销。本质上,所涉及的开销是将元数据从全局缓存复制到与特定 ObjectContext 关联的元数据中。

这种开销相对较小,因此通常不值得担心,尤其是当您考虑到使用模式固有的额外安全性时。

对我来说,您选择哪个选项取决于以下事项:

  1. 您的包装类可能存在多长时间?如果它存在很长时间,ObjectContext 可能会增长以容纳许多随着时间的推移而减速的实体。所以每次一个新的 ObjectContext 可能是个好主意。
  2. 对包装类上的方法的调用是否同步?ObjectContext 类本身不是线程安全的,因此如果您使用第二种模式,如果您希望多个线程调用它,则需要确保您的包装类/存储库是线程安全的。
  3. 这些方法本质上是无关的吗?如果是这样,如果它们在方法之间共享一个上下文,您可能会得到意想不到的副作用。

一般来说,我的建议是,如果方法是无状态的,即为每个方法触发并忘记一个新的上下文可能是一个好主意。

但是,如果您有一个相对较短的有状态形式或其他东西,那么共享上下文可能是一个更好的主意。

更新:我花时间整理了一个更完整的答案

于 2009-05-01T23:23:21.860 回答
0

如果这就是您的意思,第二个选项实际上不会自行清理。我更喜欢每次都使用 ObjectContext 版本,因为我不必在之后处理它。不确定我的问题是否正确……今天编程时间太多。

public class UserManagerRepository : IUserManagerRepository, IDisposable
{
    private readonly Entities _context = new Entities();
    private bool _disposed;

    public User Create(User user, int countryId)
    {
        user.Country = GetCountry(countryId);
        _context.AddToUser(user);
        _context.SaveChanges();
        return user;
    }
}

然后要使用这个存储库,我会执行以下操作:

using(var repository = new UserManagerRepository())
{
    repository.Create(user);
}
于 2009-05-01T21:56:35.953 回答