【问题标题】:Handle the DataContext in EntityFramework 4.0在 EntityFramework 4.0 中处理 DataContext
【发布时间】:2012-02-28 00:39:02
【问题描述】:

关于如何在 Entity Framework 4 中处理 Datacontext 是否有任何“最佳实践”?

目前,我在每个窗口中都在做这样的事情:

public class MyWindow()
{
    MyEntities() _entities;
    MyWindow()
    {
        _entities = new MyEntities();
        InitializeComponent();
    }
}

然后像这样加载到数据网格中:

    myGrid.ItemsSource= _entities.MyTable;

这不是很聪明,因为错误处理是不可能的。

我宁愿选择一个 Connection-Class 并做这样的事情:

public class MyData()
{
    public IQueryable<Product> GetAllProducts()
    {
        using(MyContext context = new MyContext())
        {
           return context.Products;
        }
    }
}

但首先,这每次都会创建一个新的上下文实例 - 这不是很糟糕吗?

或者我应该在我的 Connection-Class 中处理一个全局静态 DataContext 吗?这个静态变量不会很重载吗?

public class MyData()
{
    private static MyContext Context = new MyContext();
    public IQueryable<Product> GetAllProducts()
    {
      return Context.Products;
    }
}

【问题讨论】:

  • 请阅读神话#10 - albahari.com/nutshell/10linqmyths.aspx,希望对您有所帮助。
  • 将您的方法分组到“工作单元”中,这样​​每次创建新上下文是合乎逻辑的 - 只要工作单元正在进行,上下文就应该存在。
  • 好的,所以在每个窗口中都有一个 DataContext 没有问题,它只是将自身传递给我的 Connection-Class(仅用于异常处理情况)?

标签: c# entity-framework data-access


【解决方案1】:

在实体框架中,ObjectContext/DbContext 是一个工作单元,它们的生命周期很短。

拥有静态上下文是绝对不行的,因为这将使用大量的内存与更改跟踪实体(每个更改跟踪的实体都将被缓存和存储,直到上下文被释放)。

将上下文包装在一个 using 中,例如您的“Connection-Class”示例是执行此操作的正确方法。这通常被称为服务。

一个示例服务:

public class ProductService
{
    public IEnumerable<Product> GetAllProducts()
    {
        using(MyContext context = new MyContext())
        {
            foreach(var product in context.Products)
                yield return product;
        }
    }
}

在将处理上下文的块中返回结果集合时,请务必调用ToArray()ToList() 或使用yield return(如我的示例)。如果不这样做,则意味着在使用您的结果时,延迟执行将尝试使用已释放的上下文,这将导致运行时异常。

【讨论】:

    猜你喜欢
    • 2011-03-30
    • 2017-10-28
    • 1970-01-01
    • 2012-06-05
    • 2012-06-18
    • 1970-01-01
    • 2016-08-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多