首页 > 数据库 >C# 根据主键ID查询数据库的数据 反射和泛型实现

C# 根据主键ID查询数据库的数据 反射和泛型实现

时间:2023-04-01 19:00:32浏览次数:46  
标签:Console sql C# 查询数据库 主键 WriteLine reader prop 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语句 【泛型】 ;

标签:Console,sql,C#,查询数据库,主键,WriteLine,reader,prop,id
From: https://www.cnblogs.com/zhulongxu/p/17279113.html

相关文章

  • Perceptron, Support Vector Machine and Dual Optimization Problem (3)
    SupportVectorMachinesPerceptronandLinearSeparability假设存在一个lineardecisionboundary,它可以完美地对trainingdataset进行分割。那么,经由上述PerceptronAlgorithm计算,它将返回哪一条linearseparator?当linearseparator(即一个给定的超平面)的margi......
  • 《前端构建工具(webpack&vite)- 李立超》笔记
    1.构建工具简介1.1模块化最初我们都使用script标签来引入js,但当一个页面引入的js文件越来越多时,就产生了几个难以避免的问题:全局变量污染。变量重名。js之间的依赖关系复杂,无法保证顺序。而模块化规范就是为解决以上问题,模块内部的变量实现了在其他模块内共享。而且可以......
  • 开发一个二方包,优雅地为系统接入ELK(elasticsearch+logstash+kibana)
    去年公司由于不断发展,内部自研系统越来越多,所以后来搭建了一个日志收集平台,并将日志收集功能以二方包形式引入各个自研系统,避免每个自研系统都要建立一套自己的日志模块,节约了开发时间,管理起来也更加容易。这篇文章主要介绍如何编写二方包,并整合到各个系统中。先介绍整个ELK日志......
  • The remote name could not be resolved: 'report.dalabs.cn'
    1.在做程序的时候出现System.Net.WebException:Theremotenamecouldnotberesolved:'report.dalabs.cn'百度后得到以下方法:在webconfig文件里面添加代理配置:<system.net><defaultProxy><proxyusesystemdefault="True"proxyaddress="http://......
  • VLOOKUP 、 INDEX 、MATCH
    VLOOKUP:VLOOKUP函数是Excel中的一个纵向查找函数,它与LOOKUP函数和HLOOKUP函数属于一类函数,在工作中都有广泛应用,例如可以用来核对数据,多个表格之间快速导入数据等函数功能。功能是按列查找,最终返回该列所需查询序列所对应的值;与之对应的HLOOKUP是按行查找的。 Vlookup最容易......
  • 一个循环采集CPU的etl日志的脚本
    一个循环采集CPU的etl日志的脚本mdD:\\tempsetTargetDriveEtl=D:\\temp@echooffSET/A"index=1"SET/A"count=10":whileif%index%leq%count%(echoThevalueofindexis%index%wmicprocesswherename="wprui.exe"......
  • conda将整个环境打包,然后移植到没网环境
    参考文档:https://python-brief.com/269.html  1.在当前激活的虚拟环境中,安装2.打包3.在新环境下,创建文件夹xxx(这将来就是虚拟环境的名字),然后将文件解压4. 将离线环境包移入conda环境(本机环境在~/miniconda3/envs/)mvxxx~/miniconda3/envs/5.启动环境cond......
  • Microsoft Child Process Debugging Power Tool 插件
    使用VisualStudio2022调试Dapr应用程序 使用Dapr编写的是一个多进程的程序,两个进程之间依赖于启动顺序来组成父子进程,使用VisualStudio调试起来可能会比较困难,因为VisualStudio默认只会把你当前设置的启动项目的启动调试。好在有VisualStudio扩展(MicrosoftC......
  • Docker安装
    卸载历史版本apt-getremovedockerdocker-enginedocker.iocontainerdrunc&&apt-getpurgedocker-cedocker-ce-clicontainerd.iodocker-compose-pluginrm-rf/etc/docker&&rm-rf/usr/libexec/docker&&rm-rf/var/lib/docker&&......
  • 基于开源的 ChatGPT Web UI 项目,快速构建属于自己的 ChatGPT 站点
    作为一个技术博主,了不起比较喜欢各种折腾,之前给大家介绍过ChatGPT接入微信,钉钉和知识星球(如果没看过的可以翻翻前面的文章),最近再看开源项目的时候,发现了一个ChatGPTWebUI项目。想着刚好之前没有将ChatGPT接入过WebUI,有了这个开源项目可以拿来使用,真是不错,下面是实操的......