// 引入命名空间
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语句 【泛型】 ;

C# 根据主键ID查询数据库的数据 反射和泛型实现的更多相关文章

  1. MyBatis返回插入的主键ID(Mysql数据库)

    1.Java代码: 1.1 entity类: User.java public class User { private int userId; private String userName; pr ...

  2. 逻辑数据库设计 - 需要ID(谈主键Id)

    本文的目标就是要确认那些使用了主键,却混淆了主键的本质而造成的一种反模式. 一.确立主键规范 每个了解数据库设计的人都知道,主键对于一张表来说是一个很重要,甚至必需的部分.这确实是事实,主键是好的数据 ...

  3. Django 用散列隐藏数据库中主键ID

    最近看到了一篇讲Django性能测试和优化的文章, 文中除了提到了很多有用的优化方法, 演示程序的数据库模型写法我觉得也很值得参考, 在这单独记录下. 原文的演示代码有些问题, 我改进了下, 这里可以 ...

  4. 数据库设计时,每个表要不要都设置自增主键ID!(转)

    逻辑数据库设计 - 需要ID(谈主键Id) 本文的目标就是要确认那些使用了主键,却混淆了主键的本质而造成的一种反模式. 一.确立主键规范 每个了解数据库设计的人都知道,主键对于一张表来说是一个很重要, ...

  5. 关于mybatis插入数据库返回主键id

    关于Sequence主键的数据库来说,如: <insert id="add" parameterType="vo.Category"> <se ...

  6. Mybatis+Mysql插入数据库返回自增主键id值的三种方法

    一.场景: 插入数据库的值需要立即得到返回的主键id进行下一步程序操作 二.解决方法: 第一种:使用通用mapper的插入方法 Mapper.insertSelective(record): 此方法: ...

  7. mybatis由浅入深day01_4入门程序_4.6根据用户id(主键)查询用户信息

    4 入门程序 4.1 需求 根据用户id(主键)查询用户信息 根据用户名称模糊查询用户信息 添加用户 删除 用户 更新用户 4.2 环境 java环境:jdk1.7.0_72 eclipse:indi ...

  8. Mysql数据库表的自增主键ID号乱了,需要重新排列。

    Mysql数据库表的自增主键ID号乱了,需要重新排列. 原理:删除原有的自增ID,重新建立新的自增ID. 1,删除原有主键:ALTER TABLE `table_name` DROP `id`; 2, ...

  9. MySQL select if 查询最后一个主键 id

    查询最后一个主键id SELECT IF(MAX(id) IS NULL, 0, MAX(id)) AS maxid FROM users; 查询最小的主键id SELECT IF(MIN(id) I ...

  10. 插入Oracle数据库后返回当前主键id

    最近做一个spring版本3.0.4的老项目功能,应用场景要用到插入oracle表后返回主键ID拿来和其他表关联. 用oralce的可以一直用这种处理方式,高兼容低,搜索网上的资料都不能和这个Spri ...

随机推荐

  1. URDF(Universal Robot Description Format)—— 通用机器人描述格式URDF文件简介与生成

    参考: https://zhuanlan.zhihu.com/p/477556743 详细介绍资料: https://wiki.ros.org/urdf/XML

  2. 很好用的python游戏环境(续):强化学习算法走迷宫游戏环境(导航问题 navigation):分享一个python语言的迷宫游戏环境

    相关: 很好用的python游戏环境:强化学习算法走迷宫游戏环境(导航问题 navigation):分享一个python语言的迷宫游戏环境 前文分享了一个python下的maze游戏环境,本文再给出一 ...

  3. 【转载】 NVIDIA RTX2080ti不支持P2P Access,这是真的么?

    原文地址: http://www.gpus.cn/gpus_list_page_techno_support_content?id=30 ------------------------------- ...

  4. AI4Science 再填新成员:谷歌推出天气模型MetNet-3 已落地相关产品、谷歌天气预报模型GraphCast登刊Science —— AI天气预报大模型

    相关: https://zhidx.com/news/40169.html https://zhidx.com/news/40290.html PS. 要知道,华为公司的最高学术成果就是AI天气预报, ...

  5. 如果一个windows主机上插两个蓝牙适配器会如何???——由于 Windows 无法加载这个设备所需的驱动程序,导致这个设备工作异常。 (代码 31)——windows主机蓝牙适配器驱动错误排查

    事情是这样的,在某鱼上挂了一个蓝牙适配器,是自己多年前买的,给自己的老电脑用的,那一台老电脑主板上没有自带蓝牙,于是就在某东上买了一个蓝牙适配器: 但是这几年新买的电脑都自带蓝牙,于是准备把这个适配器 ...

  6. UITableView的原理——探究及重新实现代码

    转自简书,原文地址,本文主要探讨一些特殊细节,像视图重用这类最基本的原理可在源码里查看. 先前重新实现了一个list容器视图,由于Apple没有开源,在此分享过程中探索到的UITableView一些细 ...

  7. 记一次 .NET某环境监测系统 崩溃分析

    一:背景 1. 讲故事 前些天有位朋友找到我,说他们的程序崩溃了,也自己分析了下初步结果,让我帮忙再确认下,既然让我确认,那就开始dump分析之旅吧. 二:WinDbg 分析 1. 为什么会崩溃 wi ...

  8. CF Div3 962 E-F

    CF Div3 962 E-F E. Decode 链接: Problem - E - Codeforces 简要题意: 给你一个长度为 \(n\) 的二进制字符串\(s\) .对于每一对整数\((l ...

  9. JavaScript设计模式样例九 —— 桥接模式

    桥接模式(Bridge Pattern) 定义:是用于把抽象化与实现化解耦,使得二者可以独立变化. 目的:将抽象部分与实现部分分离,使它们都可以独立的变化. 场景:实现系统可能有多个角度分类,每一种角 ...

  10. C#ListView类的继承

    ListView控件类新加方法 新建一个类myListView class myListView : System.Windows.Forms.ListView { //添加自定义的方法 -- //设 ...