如何使用通用存储库实现 ADO.NET?

Posted

技术标签:

【中文标题】如何使用通用存储库实现 ADO.NET?【英文标题】:How to implement ADO.NET with Generic Repository? 【发布时间】:2017-07-23 11:25:02 【问题描述】:

我曾经使用 Repository、UnitOfWork 和 Dependency Injection 实现 EF。

我现在尝试使用 Repository、UnitOfWork 和依赖注入来实现 ADO.NET。- 但它会导致问题

这是我的存储库界面:

public interface IUsersRepository
    
        public User GetUser(int id);
    

这里存储库实现:

public class UsersRepository: IUsersRepository

    private readonly string _connectionString;
    public UsersRepository(string connectionString)
    
        _connectionString = connectionString;
    

    public User GetUser(int id)
    
        // Here you are free to do whatever data access code you like
        // You can invoke direct SQL queries, stored procedures, whatever 

        using (var conn = new SqlConnection(_connectionString))
        using (var cmd = conn.CreateCommand())
        
            conn.Open();
            cmd.CommandText = "SELECT id, name FROM users WHERE id = @id";
            cmd.Parameters.AddWithValue("@id", id);
            using (var reader = cmd.ExecuteReader())
            
                if (!reader.Read())
                
                    return null;
                
                return new User
                
                    Id = reader.GetInt32(reader.GetOrdinal("id")),
                    Name = reader.GetString(reader.GetOrdinal("name")),
                
            
        
    

有没有办法为 ADO.NET 创建一个“通用存储库”(如何实现它?)?

这里是控制器:

public class UsersController: Controller

    private readonly IUsersRepository _repository;
    public UsersController(IUsersRepository repository)
    
        _repository = repository;
    

    public ActionResult Index(int id)
    
        var model = _repository.GetUser(id);
        return View(model);
    

使用ADO.NET时如何制作Unitofwok? (这样做有意义吗?)

【问题讨论】:

在不回答的情况下进行标记是不公平的。 我的标记。 AFAIK,Unitofwork 意味着有一些任务在内存中进行更改,然后将这些更改应用到数据库,所以这是在 EF 创建它时通过 ADO 重新创建 Unitofwork!还有here is a good reference to Unitofwork Design Pattern. 【参考方案1】:
         /* controller */
               public class mycontroller:BaseController
                      
                       private readonly IRepo repo;

                       public mycontroller(IRepo _repo)
                       
                         _repo=repo;
                       
                       [httpGet]
                       public IActionResult<string> GetLastRecord()
                       
                         return _repo.GetLastRecord();
                       
                    
        /* repo */    
                   public class repo
                       
                          private readonly IDBContextFactory dBContextFactory; 
                          public repo(IDBContextFactory _dbContextFactory) 
                          
                               _dbContextFactory=dBContextFactory;
                          
                          public string GetLastRecord()
                            
  List< Student > studentDetails = new List<Student>();  
    studentDetails = ConvertDataTable<Student>(_dbCtextFactory.Select("mydb","select * from StudentDetail");
        /*refrence from this post https://***.com/questions/33515552/converting-datatable-to-listentity-projectdracula */;

                          
                       

        /* interface of repo */
                       public interface IRepo
                        
                          public string GetLastRecord();
                       

        /* some factory pattern for db context (multiple dbs) */
                       public class DBContextFactory
                       
                           private SqlCommand BuildFactory(string dbName)
                            
                                switch(dbName)
                                
                                    case 'mydb':
                                      return CreateMyDB();
                                
                           
                           private SqlCommand CreateMyDB()
                            
                              string connectionString = "your connection string";
                              SqlConnection connection =
                                new SqlConnection(connectionString));

                                SqlCommand command = new SqlCommand(connection);
                                return command.Open();

                           
                           //Private SqlCommand GetMyOpenCommand()
                           public DataTable Select(string dbName,string query)
                           


                                   SqlDataAdapter dataAdapter=new SqlDataAdapter();
                                   dataAdapter.SelectCommand=BuildFactory(dbName);
                                  DataTable dt =new DataTable();
                                   dataAdapter.Fill(dt);
                                   con.Close();
                                   return dt;
                           

                       
        /* factory in dependncy pattern */
                  public inteface IDBContextFactory
                   
                     SqlCommand BuildFactory(string dbName);
                     SqlCommand CreateMyDB();
                     DataTable Select(string dbName,string query)
                
        /****** HERE IS YOUR GENERIC FILE ******/
        private static List<T> ConvertDataTable<T>(DataTable dt)  
          
            List<T> data = new List<T>();  
            foreach (DataRow row in dt.Rows)  
              
                T item = GetItem<T>(row);  
                data.Add(item);  
              
            return data;  
        

        private static T GetItem<T>(DataRow dr)  
          
            Type temp = typeof(T);  
            T obj = Activator.CreateInstance<T>();  

            foreach (DataColumn column in dr.Table.Columns)  
              
                foreach (PropertyInfo pro in temp.GetProperties())  
                  
                    if (pro.Name == column.ColumnName)  
                        pro.SetValue(obj, dr[column.ColumnName], null);  
                    else  
                        continue;  
                  
              
            return obj;  
         
        /***** END OF GENERIC PART *****/
    /* USAGE OF GENERIC */
    List< Student > studentDetails = new List<Student>();  
    studentDetails = ConvertDataTable<Student>(dt);

【讨论】:

以上是关于如何使用通用存储库实现 ADO.NET?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 ASP.NET Core MVC 中使用 ADO.NET 向存储过程添加参数?

ADO.NET 执行部分更新/插入

在 ASP.Net Core 项目中使用 ADO.Net 将 JSON 类型作为参数传递给 SQL Server 2016 存储过程

使用 ADO.NET 传递表值参数

如何使用 Visual Studio 将 XAMPP MySQL 连接到 ADO.NET Entity Framework?

使用 ADO.NET 为 MVC 3 应用程序设计 DAL 的最佳方法?