C# 根据主键ID查询数据库的数据 反射和泛型实现
// 引入命名空间 using Zhu.ADO.NET.DBProxy; using Zhu.ADO.NET.Models.models; Console.WriteLine("========================================================"); Console.WriteLine("============开始测试===================================="); Console.WriteLine("========================================================"); // 使用了 try 命令框就不会直接消失了 try { DBProxyCore dBProxyCore = new DBProxyCore(); { // 新家一个类型 //Console.WriteLine(123); // 调用基于主键 id 获取数据库的方法 GetCommodity // ps:1. 引入命名空间 // 2. 创建一个类型 【就是类class == 就可以调用这个类下面的所有方法了】 //dBProxyCore.GetCommodity(20007); //Console.WriteLine(dBProxyCore.GetCommodity(20016)); } { // 一个方法满足不同不同的实体查询 -- 泛型 // 泛型方法 泛型类 泛型接口 泛型委托 Commodity commodity = dBProxyCore.Find<Commodity>(20007); Commony commony = dBProxyCore.Find<Commony>(13398); // Console.WriteLine(123); Console.WriteLine(123); Console.WriteLine(123); } { // 反射是程序员的快乐 } } catch (Exception ex) { Console.WriteLine(ex.Message); }
核心代码:
using Microsoft.VisualBasic; using System.Data.SqlClient; using Zhu.ADO.NET.Models.models; namespace Zhu.ADO.NET.DBProxy { /// <summary> /// 他就是用来操作数据库的核心代理 /// 增删改查 /// /// 1. 先来一个查询 -- 基于主键查询 /// </summary> public class DBProxyCore { /// <summary> /// 主键查询 返回 /// </summary> /// <returns></returns> #region 这是一个获取商品的方法 //public Commodity GetCommodity(int id) //{ // Console.WriteLine("进入"); // // 新语法中 using 不在需要大括号 {} 括起来的 // Commodity commodity = new Commodity(); // 创建一个 commodity 对象 用来存放数据的 // //Console.WriteLine(commodity); // string constr = "Data Source=joker;Initial Catalog=AdvancedCustomerDB;Integrated Security=True;User ID=root;Password=abc123"; // //Console.WriteLine(constr); // using (SqlConnection conn = new SqlConnection(constr)) // { // conn.Open(); // 打开链接 // Console.WriteLine($"状态:{conn.State}"); // // 转杯 sql 语句 【查询】 // string sql = @$"SELECT [Id] // ,[ProductId] // ,[CategoryId] // ,[Title] // ,[Price] // ,[Url] // ,[ImageUrl] // FROM [AdvancedCustomerDB].[dbo].[Commodity] where id={id}"; // // 创建一个命令执行对象 // SqlCommand cmd = conn.CreateCommand(); // // 给这个对象一个执行命令 【就是sql语句】 // cmd.CommandText = sql; // SqlDataReader reader = cmd.ExecuteReader(); // 读取数据 // if (reader.Read()) // { // Console.WriteLine(commodity); // commodity.id = Convert.ToInt32(reader["id"]); // ps:id 是int类型所以要转换 // commodity.ProductId = Convert.ToInt32(reader["ProductId"]); // commodity.CategoryId = Convert.ToInt32(reader["CategoryId"]); // //commodity.Createtime = Convert.ToDateTime(reader["CategoryId"]); // commodity.Price = Convert.ToDecimal(reader["CategoryId"]); // // 转换字符串类型 ToString // commodity.ImageUrl = reader["ImageUrl"].ToString(); // commodity.Url = reader["Url"].ToString(); // Console.WriteLine(commodity.id); // } // } // return new Commodity(); //必须返回一个commodity实体回去 //} #endregion // 泛型改写 public T Find<T>(int id) where T:new() // 必须加上约束 否则报错的 { Console.WriteLine("进入泛型方法"); // 新语法中 using 不在需要大括号 {} 括起来的 //T model = new T(); // 创建一个 T类型的 对象 用来存放数据的 最终返回的数据 // 通过反射创建对象 // 使用反射来替换 T model //type.name 就是数据库的表的名称 也就是实体类的名字 Type type = typeof(T); // 获取泛型的类型 // object 可以为空 object? oResult = Activator.CreateInstance(type); // 创建反射对象 调用无参数构造函数 //Console.WriteLine(commodity); string constr = "Data Source=joker;Initial Catalog=AdvancedCustomerDB;Integrated Security=True;User ID=root;Password=abc123"; //Console.WriteLine(constr); using (SqlConnection conn = new SqlConnection(constr)) { conn.Open(); // 打开链接 Console.WriteLine($"状态:{conn.State}"); // 转杯 sql 语句 【查询】 // 通过反射设置不同的 sql 语句 // sql 语句应该依赖于泛型T 通过T来动态生成不同的sql语句 //List<string> propNameList = type.GetProperties().Select(c => c.Name).ToList(); // propNameList 的数据格式 //[0]: "id" //[1]: "ProductId" //[2]: "CategoryId" //[3]: "Title" //[4]: "Price" //[5]: "Url" //[6]: "ImageUrl" //Console.WriteLine(propNameList); // 改造 以逗号分割 // ps:type.GetProperties() 里面实时 T 实体 【泛型】的属性 //List<string> propNameList = new List<string>(); //foreach(var prop in type.GetProperties()) //{ // propNameList.Add(prop.Name); //} //string strProp = string.Join(",", propNameList); //strProp = "id,ProductId,CategoryId,Title,Price,Url,ImageUrl" // strProp 就是我们所需要的数据格式类型 //string sql = @$"SELECT [Id] // ,[ProductId] // ,[CategoryId] // ,[Title] // ,[Price] // ,[Url] // ,[ImageUrl] // FROM [AdvancedCustomerDB].[dbo].[Commodity] where id={id}"; // 最终的泛型的通用的sql语句 //string sql = $"select {strProp} from {type.Name} where id=" + id; // 经过简化的sql语句 string sql = $"select {string.Join(",", type.GetProperties().Select(c => c.Name).ToList())} from {type.Name} where id=" + id; // 创建一个命令执行对象 SqlCommand cmd = conn.CreateCommand(); // 给这个对象一个执行命令 【就是sql语句】 cmd.CommandText = sql; SqlDataReader reader = cmd.ExecuteReader(); // 读取数据 if (reader.Read()) { // 绑定如何通用??? // 现在 model 是泛型是没有 id 等这些属性的 // 解决办法 使用反射解决 //model.id = Convert.ToInt32(reader["id"]); // ps:id 是int类型所以要转换 //model.ProductId = Convert.ToInt32(reader["ProductId"]); //model.CategoryId = Convert.ToInt32(reader["CategoryId"]); //model.Createtime = Convert.ToDateTime(reader["CategoryId"]); //model.Price = Convert.ToDecimal(reader["Price"]); //转换字符串类型 ToString //model.ImageUrl = reader["ImageUrl"].ToString(); //model.Url = reader["Url"].ToString(); // 通过反射赋值 给对象的属性赋值 // 1. 获取属性 // 2. 通过属性对象调用SetValue方法 // 循环遍历所有的属性逐个给属性赋值 foreach (var prop in type.GetProperties()) { // 把表字段的值赋值给对象属性 Equals 用来判断是否相等 // 但是这样依然不能当作泛型的方法来使用 prop.SetValue(oResult, reader[prop.Name]); Console.WriteLine("sucess"); // oResult就是最后的返回数据 // SetValue 赋值内置函数 //if (prop.Name.Equals("id")) //{ // prop.SetValue(oResult, reader[prop.Name]); //} //else if (prop.Name.Equals("ProductId")) //{ // prop.SetValue(oResult, reader["ProductId"]); //} //else if (prop.Name.Equals("CategoryId")) //{ // prop.SetValue(oResult, reader["CategoryId"]); //} //else if (prop.Name.Equals("Title")) //{ // prop.SetValue(oResult, reader["Title"]); //} //else if (prop.Name.Equals("Price")) //{ // prop.SetValue(oResult, reader["Price"]); //} //else if (prop.Name.Equals("Url")) //{ // prop.SetValue(oResult, reader["Url"]); //} //else if (prop.Name.Equals("ImageUrl")) //{ // prop.SetValue(oResult, reader["ImageUrl"]); //} //Console.WriteLine(oResult.Price); } } } return (T)oResult; //必须返回一个 oResult 实体回去 [ 强转换 ] } } }
string sql = $"select {string.Join(",", type.GetProperties().Select(c => c.Name).ToList())} from {type.Name} where id=" + id;
通用的sql语句 【泛型】 ;