处理我的ObjectContext的正确方法是什么?

时间:2013-06-27 13:59:18

标签: c# asp.net-mvc-3 entity-framework .net-3.5 datacontext

我不太确定Dispose我的ObjectContext的正确方法是什么。以下是我的设置方法:

public abstract class DataManagerBase<T> where T:ObjectContext
{
    protected T _context = null;

    public string Message { get; set; }

    public DataManagerBase(T context)
    {
       _context = context;
    }
}

要在其他课程中使用它,我正在做类似的事情:

public class Test : DataManagerBase<DataEntities>
{
     public Test(DataEntities context) 
        : base(context){}

     public void InsertRecord(Person p)
     {
         if(_context != null)
         {
             try
             {
                 //Do insert logic
             }
             catch(Exception ex)
             {

             }
         }
    }

}

我有其他方法使用相同的_context,所以我没有使用using语句,所以如果抛出异常,我应该检查_context是否为空然后处置它?基本上我想确保_context在我完成时被处理,无论是否有异常。是否会向每个finally添加try/catch不正确?

将此方法添加到我的DataManagerBase类中,然后在其他类中调用它可以解决这个问题:

 public void DisposeContext()
 {
        if (_context != null)
        {
            _context.Dispose();
        }
 }

4 个答案:

答案 0 :(得分:5)

拇指的规则是:不要处理你没有创建的对象。因此,您不应将您的上下文置于您提供的任何类中。

但是,您应该在课程中调用context.Dispose(),您实际创建此特定实例。当你这样做时 - 应该没有其他对象使用它。你要做的是避免设计问题,而不是修复它。这是错的,imho。当你忘记在某个地方再次进行无效检查时,这会让你筋疲力尽。

使用您提供的代码示例如下:

void SomeMethodInOuterScope()
{
    var context = new DataEntities();

    var test = new Test(context);

    try
    {
        test.InsertRecord(new Person());
        ...............
    }
    catch(Exception ex)
    {
        ....
    }
    finally
    {
        context.Dispose();
    }
}

这是另一个例子(当上下文不是本地的时候)

class SomeClassInOuterScope : IDisposable
{
    private DataEntities _context;

    public SomeClassInOuterScope()
    {
        _context = new DataEntities();
    }

    public void Test()
    {
        var test = new Test(_context);
        test.InsertRecord(new Person());
        ...............
    }

    public void Dispose()
    {
        _context.Dispose();
    }
}

void SomeMethodInOuterOuterScope()
{
    var someclass = new SomeClassInOuterScope();

    try
    {
        someclass.Test();
        ...............
    }
    catch(Exception ex)
    {
        ....
    }
    finally
    {
        someclass.Dispose();
    }
}

答案 1 :(得分:3)

最好是在一个地方创建和删除它。像

using(var context = factory.CreateContext())
{
    // use your context
}

答案 2 :(得分:0)

您是否可以在抽象类中添加Dispose方法。也许实现IDisposable。

让调用代码的提供者使用using块。

所以在抽象类上:

 public void Dispose()
 {
        if (_context != null)
        {
            _context.Dispose();
        }
 }

致电代码:

using(var db = new Test())
{
... 
}

这样做的缺点是你依靠调用代码来管理上下文的一次性用法。

答案 3 :(得分:0)

尽管可能需要处理上下文,但并非绝对必要。垃圾收集器最终将处理它,实体框架使用ado.net连接池,因此它不会真正保持连接。

这样做并不是最有效的,但它不会导致任何泄漏,除非你的班级本身有泄漏。每当您的Test类超出范围时,上下文最终将由gc处理。

如果你反复创建很多这些对象,你真的只会担心,情况可能并非如此。

我并不是说这是一个很好的做法,但如果这是某种类型的错误修复,或者是暂时性的事情......可能没有必要。