如何在 MVC 控制器中实现数据访问层

Posted

技术标签:

【中文标题】如何在 MVC 控制器中实现数据访问层【英文标题】:How to implement a data access layer within MVC Controller 【发布时间】:2017-10-19 14:30:48 【问题描述】:

我了解数据访问层或简称 DAL 用于访问和检索数据库中的信息,但我不确定如何在控制器中调用 DAL 数据。 例如,我在我的 DAL 中创建了这个静态类,但我不确定如何将它调用到我的控制器,任何帮助或指南将不胜感激。 DohvatiMetodu 是类的名称。

public static FormInputViewModel DohvatiMetodu()
        
            var viewModel = new FormInputViewModel();
            var metoda = new List<Metoda>();
            var metodaList = new List<SelectListItem>();

            using (var db = new ApplicationDbContext())
            
                metoda = db.Metoda.ToList();
            

            foreach (var metod in metoda)
            
                metodaList.Add(new SelectListItem() Value = metod.Id.ToString(), Text = metod.Naziv);
            

            viewModel.KoristenaMetoda = metodaList;


            return viewModel;

【问题讨论】:

DAL 是单独的类文件,用于对数据库执行 CRUD 操作。您可以直接从控制器调用StaticClass.MethodName()。从控制器访问 DAL 没有任何限制,也不会破坏 MVC 中的任何规则。 如果它是一个静态方法,你只需通过ClassName.MethodName 访问它,假设你在范围内有正确的命名空间。当然,现在更常见的是不将事物设为静态,而是使用依赖注入将类放入您的控制器中。 感谢您提供的信息,但我对依赖注入形式的外观很感兴趣? 检查下面的答案 嘎啊啊啊啊啊啊啊啊啊。不要写静态的。这使得模拟/单元测试变得非常困难。 【参考方案1】:

根据用户的许多要求,我使用简单的 CRUD 方法逐步更新了具有完整 存储库模式 的代码:

存储库模式在应用程序的数据层和域层之间添加了一个分离层。它还使应用程序的数据访问部分具有更好的可测试性。

数据库工厂 (IDatabaseFactory.cs):

public interface IDatabaseFactory : IDisposable

    Database_DBEntities Get();

数据库工厂实现(DatabaseFactory.cs):

public class DatabaseFactory : Disposable, IDatabaseFactory

    private Database_DBEntities dataContext;
    public Database_DBEntities Get()
    
        return dataContext ?? (dataContext = new Database_DBEntities());
    

    protected override void DisposeCore()
    
        if (dataContext != null)
            dataContext.Dispose();
    

基础接口 (IRepository.cs):

public interface IRepository<T> where T : class

    void Add(T entity);
    void Update(T entity);
    void Detach(T entity);
    void Delete(T entity);
    T GetById(long Id);
    T GetById(string Id);
    T Get(Expression<Func<T, bool>> where);
    IEnumerable<T> GetAll();
    IEnumerable<T> GetMany(Expression<Func<T, bool>> where);
    void Commit();

抽象类(Repository.cs):

 public abstract class Repository<T> : IRepository<T> where T : class
    
        private Database_DBEntities dataContext;
        private readonly IDbSet<T> dbset;
        protected Repository(IDatabaseFactory databaseFactory)
        
            DatabaseFactory = databaseFactory;
            dbset = DataContext.Set<T>();

        

        /// <summary>
        /// Property for the databasefactory instance
        /// </summary>
        protected IDatabaseFactory DatabaseFactory
        
            get;
            private set;
        

        /// <summary>
        /// Property for the datacontext instance
        /// </summary>
        protected Database_DBEntities DataContext
        
            get  return dataContext ?? (dataContext = DatabaseFactory.Get()); 
        

        /// <summary>
        /// For adding entity
        /// </summary>
        /// <param name="entity"></param>
        public virtual void Add(T entity)
        

            try
            
                dbset.Add(entity);
                //  dbset.Attach(entity);
                dataContext.Entry(entity).State = EntityState.Added;
                int iresult = dataContext.SaveChanges();
            
            catch (UpdateException ex)
            

            
            catch (DbUpdateException ex) //DbContext
            

            
            catch (Exception ex)
            
                throw ex;
            

        

        /// <summary>
        /// For updating entity
        /// </summary>
        /// <param name="entity"></param>
        public virtual void Update(T entity)
        
            try
            
                // dbset.Attach(entity);
                dbset.Add(entity);
                dataContext.Entry(entity).State = EntityState.Modified;
                int iresult = dataContext.SaveChanges();
            
            catch (UpdateException ex)
            
                throw new ApplicationException(Database_ResourceFile.DuplicateMessage, ex);
            
            catch (DbUpdateException ex) //DbContext
            
                throw new ApplicationException(Database_ResourceFile.DuplicateMessage, ex);
            
            catch (Exception ex) 
                throw ex;
            
        



        /// <summary>
        /// for deleting entity with class 
        /// </summary>
        /// <param name="entity"></param>
        public virtual void Delete(T entity)
        
            dbset.Remove(entity);
            int iresult = dataContext.SaveChanges();
        


        //To commit save changes
        public void Commit()
        
            //still needs modification accordingly
            DataContext.SaveChanges();
        

        /// <summary>
        /// Fetches values as per the int64 id value
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public virtual T GetById(long id)
        
            return dbset.Find(id);
        

        /// <summary>
        /// Fetches values as per the string id input
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public virtual T GetById(string id)
        
            return dbset.Find(id);
        

        /// <summary>
        /// fetches all the records 
        /// </summary>
        /// <returns></returns>
        public virtual IEnumerable<T> GetAll()
        
            return dbset.AsNoTracking().ToList();
        

        /// <summary>
        /// Fetches records as per the predicate condition
        /// </summary>
        /// <param name="where"></param>
        /// <returns></returns>
        public virtual IEnumerable<T> GetMany(Expression<Func<T, bool>> where)
        
            return dbset.Where(where).ToList();
        

        /// <summary>
        /// 
        /// </summary>
        /// <param name="entity"></param>
        public void Detach(T entity)
        
            dataContext.Entry(entity).State = EntityState.Detached;
        

        /// <summary>
        /// fetches single records as per the predicate condition
        /// </summary>
        /// <param name="where"></param>
        /// <returns></returns>
        public T Get(Expression<Func<T, bool>> where)
        
            return dbset.Where(where).FirstOrDefault<T>();
        

    

现在的重点是如何在控制器中访问此存储库模式,我们开始:

1.你有用户模型:

public partial class User

        public int Id  get; set; 
        public string Name  get; set; 

2。现在您必须创建 UserModel 的存储库类

public class UserRepository : Repository<User>, IUserRepository

    private Database_DBEntities dataContext;

    protected IDatabaseFactory DatabaseFactory
    
        get;
        private set;
    

    public UserRepository(IDatabaseFactory databaseFactory)
        : base(databaseFactory)
    
        DatabaseFactory = databaseFactory;
    

    protected Database_DBEntities DataContext
    
        get  return dataContext ?? (dataContext = DatabaseFactory.Get()); 
    

  public interface IUserRepository : IRepository<User>
   
  

3.现在您必须使用所有 CRUD 方法创建 UserService 接口 (IUserService.cs):

public interface IUserService
 

     #region User Details 
     List<User> GetAllUsers();
     int SaveUserDetails(User Usermodel);
     int UpdateUserDetails(User Usermodel);
     int DeleteUserDetails(int Id);
     #endregion


4.现在您必须使用所有 CRUD 方法创建用户服务接口 (UserService.cs):

public class UserService : IUserService

  IUserRepository _userRepository;
  public UserService()  
  public UserService(IUserRepository userRepository)
  
   this._userRepository = userRepository;
  
  public List<User> GetAllUsers()
  
      try
      
          IEnumerable<User> liUser = _userRepository.GetAll();
          return liUser.ToList();
      
      catch (Exception ex)
      
          throw ex;
      
  
   /// <summary>
   /// Saves the User details.
   /// </summary>
   /// <param name="User">The deptmodel.</param>
   /// <returns></returns>
   public int SaveUserDetails(User Usermodel)
   
       try
       
           if (Usermodel != null)
           
               _userRepository.Add(Usermodel);
               return 1;
           
           else
               return 0;
       
       catch
       
           throw;
       

   

   /// <summary>
   /// Updates the User details.
   /// </summary>
   /// <param name="User">The deptmodel.</param>
   /// <returns></returns>
   public int UpdateUserDetails(User Usermodel)
   
       try
       
           if (Usermodel != null)
           
               _userRepository.Update(Usermodel);
               return 1;
           
           else
               return 0;
       
       catch
       
           throw;
       
   

   /// <summary>
   /// Deletes the User details.
   /// </summary>
   /// <param name="Id">The code identifier.</param>
   /// <returns></returns>
   public int DeleteUserDetails(int Id)
   
       try
       
           User Usermodel = _userRepository.GetById(Id);
           if (Usermodel != null)
           
               _userRepository.Delete(Usermodel);
               return 1;
           
           else
               return 0;
       
       catch
       
           throw;
       
   


5.现在你已经为你的存储库模式设置好了,你可以访问用户控制器中的所有数据:

//Here is the User Controller 
public class UserProfileController : Controller


    IUserService _userservice;
    public CustomerProfileController(IUserService userservice)
    
        this._userservice = userservice;
    

    [HttpPost]
    public ActionResult GetAllUsers(int id)
    
    User objUser=new User();

    objUser = _userservice.GetAllUsers().Where(x => x.Id == id).FirstOrDefault();

    

干杯!!

【讨论】:

以上是关于如何在 MVC 控制器中实现数据访问层的主要内容,如果未能解决你的问题,请参考以下文章

干货理解理解javascript中实现MVC的原理

如何在我的 Web MVC 应用程序中实现访问控制列表?

MVC中数据访问层和模型的区别

如何在C#中实现OPC数据访问

服务层和数据访问对象层如何适应 Spring MVC 架构?

如何在 Firebase 中实现基于角色的访问控制