Как мне написать репозиторий с эффективным Dispose () в EF 3.5 -4.0? - PullRequest
0 голосов
/ 07 декабря 2010

Я пытаюсь написать своего рода репозиторий для эффективного добавления, обновления, удаления и т. Д. Но я так растерялся, как я могу избавиться от своего 2 класса (ErpEntities и DataRepository), есть больше советов, но также и больше конфликтов в Google.Я хочу сделать избавиться от возвращаемого значения.Кратко и эффективно :( С наилучшими пожеланиями ...

namespace WinApp.EF
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            using (ErpEntities erp = new ErpEntities())
            {
                erp.SaveCustomer(textBox1.Text, textBox2.Text);
            }
        }
    }

    public class ErpEntities : IDisposable
    {

        public int SaveCustomer(string Name, string SurName)
        {
            using (DataRepository<Customer> repository = new DataRepository<Customer>(new TestErpEntities()))
            {
                return repository.Add(new Customer() { Name = Name, SurName = SurName });
            }
        }

        public void Dispose()
        {
            GC.SuppressFinalize(this);
        }

    }


    public interface IRepository<T> : IDisposable where T : class
    {
         int Add(T entity);
    }

    public class DataRepository<T> : IRepository<T> where T : class
    {

        private TestErpEntities _context;

        public DataRepository()
        {
        }   

       public DataRepository(TestErpEntities context)
        {
            _context = context;
        }

        public int Add(T entity)
        {
            _context.AddObject(typeof(T).Name, entity);
            int saveValue = _context.SaveChanges();
            return saveValue;
        }

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

    }
}

Ответы [ 2 ]

2 голосов
/ 07 декабря 2010

Я думаю, это то, что вы хотите:

public class ErpEntities : IDisposable 
{ 

    public int SaveCustomer(string Name, string SurName) 
    {
        using(DataRepository repository = new DataRepository<Customer>(new TestErpEntities()))
        { 
           return repository.Add(new Customer() { Name = Name, SurName = SurName });  
        } // This using statment ensures that the DataRepository is Dispose()'d when the method exits
    } 


    #region IDisposable Members 

    public void Dispose() 
    { 
       // You could eliminate this as there's nothing in your 
       // ErpEntities class that needs disposing
    } 

    #endregion 
} 

public class DataRepository<T> : IRepository<T> where T : class     
{     

    private TestErpEntities _context;     

    public DataRepository()     
    {     
    }     

    public DataRepository(TestErpEntities context)     
    {     
        _context = context;     
    }     

    public int Add(T entity)     
    {     
        _context.AddObject(typeof(T).Name, entity);     
        int saveValue = _context.SaveChanges();     
        return saveValue;     
    }     


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

Деструктор класса (~DataRepository()) и GC.SupressFinalizer() не нужны, потому что у вас нет неуправляемых ресурсов для освобождения. Многие утверждают, что это часть шаблона IDisposable, но, по-моему, это не нужно.

Также это:

new DataRepository<Customer>().Dispose(); 

полностью избыточен и не нужен. Здесь вы создаете этот объект только , чтобы уничтожить его. Он не имеет никакой другой функции и является просто потерей циклов памяти / процессора.

1 голос
/ 07 декабря 2010

Из того, что вы опубликовали, ErpEntities не нужно реализовывать IDisposable.Он ничего не «владеет».

Если это так, new ErpEntities().SaveCustomer(...) будет неправильным способом его использования.

Классу DataRepository не нужен деструктор (~DataRepository()), и вызов (ы) на GC.SuppressFinalize(this) также могут быть удалены.

То, что вам нужно оставить:

  • если класс содержит (владеет) класс IDisposable, он должен также реализовать IDisposable и перенаправить вызовы Dispose ()

  • вызывающий код должен использовать IDisposable классы в блоке using(...) { }.

  • не связывайтесь с деструкторами, если у вас нет неповрежденного ресурса (и даже тогда есть лучшие варианты)

...