Entity Framework 4.1 Database First Dependency Injection Unit of Work

前端 未结 1 390
青春惊慌失措
青春惊慌失措 2021-01-07 12:12

Ok, there are tons of examples using unit of work with dependency injection for Code First, using generic repositories and all that good stuff.

Does anyone have an e

相关标签:
1条回答
  • 2021-01-07 12:29

    The context for code first or dbfirst will be the same (DbContext).

    Stored procedures are mapped in your repository instead of calling context.Customers you call context.Database.Query("Proc_whatever").

    Is there a specific spot you want help on, I may have a code sample for it, but everything above is done the same way as the di, code first, generic repositories, etc. The only change to implement a UnitOfWork is to ensure your repositories don't call SaveChanges, you have a method on your UnitOfWork interface called Save() that in turn calls save changes.

    I'll update the code at https://github.com/adamtuliper/EF5-for-Real-Web-Applications to include a unit of work. I dont like the implementation though, something doesn't feel right, and thus is leading me more towards CQRS I believe.

    So the idea here is: Inject IUnitOfWork IUnitOfWork contains an IContext which is also injected and mapped to a Context. IUnitOfWork maps to UnitOfWork concrete implementation. UnitOfWork concrete implementation references the repositories:

    This is partially off the top of my head, so excuse any compilation errors, it's to show in principle

    
    public class YourContext : DbContext, IContext
    {
       //just a regular DbContext class except use IDbSet
       public IDbSet Customers { get; set; }
    }
    
    public interface IUnitOfWork
    {
         ICustomerRepository CustomerRepository { get; }
         IOrderRepository OrderRepository { get; }
         void Save();
    }
    
    
    
     public class UnitOfWork : IUnitOfWork, IDisposable
     {
            private readonly IContext _context;
            private ICustomerRepository _customerRepository;
            private IOrderRepository _orderRepository;
            private bool _disposed = false;
    
            public UnitOfWork(IContext context)
            {
                _context = context;
            }
    
            public ICustomerRepository CustomerRepository
            {
                get
                {
                    if (this._customerRepository == null)
                    {
                        this._customerRepository = new CustomerRepository(_context);
                    }
                    return _customerRepository;
                }
            }
    
            protected virtual void Dispose(bool disposing)
            {
                if (!this._disposed)
                {
                    if (disposing)
                    {
                        ((IDisposable)_context).Dispose();
                    }
                }
                this._disposed = true;
            }
    
            public void Dispose()
            {
                Dispose(true);
                GC.SuppressFinalize(this);
            }
    
    
    public class CustomerController : Controller
    {
       private readonly IUnitOfWork _unitOfWork;
       public CustomerController(IUnitOfWork unitOfWork)
       {
          _unitOfWork = unitOfWork;
       }
    
       [AutoMap(typeof(Customer), typeof(CustomerIndexViewModel)]
       public ActionResult Index()
       {
            return _unitOfWork.CustomersRepository.GetAll();
            //or if not using AutoMapper, use the viewmodel directly:
            //return _unitOfWork.CustomersRepository.GetAll().Select(c => new CustomerIndexViewModel
                                                        {
                                                            CustomerId = c.CustomerId,
                                                            Address = c.Address,
                                                            City = c.City,
                                                            State = c.State,
                                                            FirstName = c.FirstName,
                                                            LastName = c.LastName
                                                        }).ToArray(); ;
       }
    }
    

    To use a proc, in the CustomerRepository you'd do the following:

    
    public Customer GetById(int id)
    {
          return this.Context.Database.SqlQuery("Proc_GetCustomer @customerID", new SqlParameter("@customerID", id)).Single();
          //instead of:  return this.Context.Customers.Include(o => o.Orders).Single(o => o.CustomerId == id);
    }
    
    
    0 讨论(0)
提交回复
热议问题