C#反射在数据库操作中的应用(反射属性,反射字段)
这几天学习反射的应用,今天把其应用到数据操作中
现记录学习笔记
环境为:
编译器:vs2017
数据库:access
反射类型为:字段
1先在类文件的定义是用哪种数据库,和用字段还是属性来反射
本例是:Access数据库+反射字段
#define OLEDB_ //access数据库
#define FIELDS_ //反射字段
2.定义数据库操作类的别名,用来区分数据库操作要用的函数
定义是反射的是字段还是反射的是属性
//区分是用哪种数据库
#if OLEDB_ //access
using MyConnection = OleDbConnection;
using MyCommand = OleDbCommand;
using MyDataAdapter = OleDbDataAdapter;
using MyCommandBuilder = OleDbCommandBuilder;
using MyParameter = OleDbParameter;
using MyDataRead = OleDbDataReader;
//...
#elif SQL_ //sql
using MyCommand = SqlCommand;
using MyConnectin = SqlConnection;
using MyDataAdapter = SqlDataAdapter;
using MyCommandBuilder = SqlCommandBuilder;
using MyParameter = SqlParameter;
using MyDataRead = SqlDataReader;
//.... #endif //区分是用类的字段还是类的属性,
#if FIELDS_
using MyInfo = FieldInfo;//字段
#elif POPRS_
using MyInfo = PropertyInfo;//属性 #endif
3.在类中定义方法来选择反射的样式
//单表模板操作类
//T 为和数据库中要操作的表一样的类或结构体
//可以反射属性,也可以反射字段
class BDAdo<T>
{
/// <summary>
/// 获得属性列表,或是字段列表
/// </summary>
/// <returns></returns>
private MyInfo[] GetInfos()
{
#if FIELDS_ //字段
return typeof(T).GetFields();
#elif POPRS_ //属性
return typeof(T).GetProperties();
#endif
}
}
下面就是在类的各种操作的实现
4.获得查询结果的表
/// <summary>
/// 查询指定条件的列表数据
/// </summary>
/// <param name="findsql"> 指定查询条件,为NULL就查询全部数据</param>
/// <returns></returns>
public DataTable GetDataTable(string findsql = null)//查询条件字符串,也就是Sql语句查询的 where 后面的条件语句
{
Type ty = typeof(T);
// string fName = string.Join(",", ty.GetFields().Select(p => p.Name));
string sql = $"select * from [{ty.Name}]";
if (findsql != null)
sql += $" where {findsql}"; DataTable dt = new DataTable();
conn = new MyConnection(conStr);
MyDataAdapter da = new MyDataAdapter(sql, conn); try
{
da.Fill(dt);
return dt;
}
finally
{
conn.Close();
da.Dispose();
}
}
5.添加数据
/// <summary>
/// 插入数据
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="t"></param>
/// <returns></returns>
public bool InsertData(T t)
{
//获得对象的类型
Type ty = t.GetType(); //拼接添加数据的Sql语句
string intoSql = $"INSERT INTO [{ty.Name}] ({GetFildeNames()}) VALUES ({GetFileParams()})"; conn = new MyConnection(conStr);
MyCommand cmd = conn.CreateCommand();
cmd.CommandText = intoSql;
cmd.Parameters.AddRange(GetParameters(t)); try
{
conn.Open();
return cmd.ExecuteNonQuery() == 1;
}
finally
{
cmd.Dispose();
conn.Close();
}
}
6 根据字段或是属性获得参数化列表
/// <summary>
/// 获得参数化列表
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="t"></param>
/// <returns></returns>
private MyParameter[] GetParameters(T t)
{
Type ty = typeof(T);
List<MyParameter> parList = new List<MyParameter>();
foreach (var v in GetInfos())
{
MyParameter pr = new MyParameter($"@{v.Name}", v.GetValue(t));
parList.Add(pr);
}
return parList.ToArray();
}
7.获得字段或是属性名称组成的字符串
/// <summary>
/// 获得类的字段名或属性名,组成的字符串
/// </summary>
/// <param name="ty"></param>
/// <returns></returns>
private string GetFildeNames()
{
Type ty = typeof(T);
return string.Join(",", GetInfos().Select(p => $"[{p.Name}]"));
}
样式:
name,sex,age,tel,adds
8.获得字段或是属性名称组成的参数格式字符串
/// <summary>
/// 获得类的字段名或是属性名,并以参数化样式(@name)组成的字符串
/// </summary>
/// <param name="ty"></param>
/// <returns></returns>
private string GetFileParams()
{
Type ty = typeof(T);
return string.Join(",", GetInfos().Select(p => $"@{p.Name}"));
}
//样式:
@name,@sex,@age,@tel,@adds
9.对数据库的增,删,改,执行命令
1可以是Sql语句操作,
2也可以是参数化列表操作,
3也可以是储存过程操作
/// <summary>
/// Sql语句执行命令(insert,delete,update)
/// </summary>
/// <param name="sql"></param>
/// <param name="cmdType"></param>
/// <param name="pars"></param>
/// <returns></returns>
public int ExecuteNonQuery(string sql, CommandType cmdType = CommandType.Text,
params MyParameter[] pars)
{
conn = new MyConnection(conStr); MyCommand cmd = conn.CreateCommand();
cmd.CommandType = cmdType;
cmd.CommandText = sql;
if (pars.Length > 0)
{
cmd.Parameters.Clear();
cmd.Parameters.AddRange(pars);
} try
{
conn.Open();
return cmd.ExecuteNonQuery();
}
finally
{
conn.Close();
cmd.Dispose();
}
}
10.查询指定条件,返回一个对象实例
/// <summary>
/// 查询指定条件的对象
/// </summary>
/// <param name="cxSql"></param>
/// <returns></returns>
public T FindOneObject(string cxSql)
{
Type ty = typeof(T);
//string sql = $"select {GetFildeNames()} from {ty.Name} where {cxSql}";
object obj = Activator.CreateInstance(ty);
DataTable dt = GetDataTable(cxSql);
if (dt.Rows.Count == 0)
return default(T); foreach (var v in GetInfos())
{ SetObjectValue(v, dt.Rows[0][$"{v.Name}"], ref obj);
}
return (T)obj;
}
SetObjectValue()
/// <summary>
/// 设置字段或是属性相应的值
/// </summary>
/// <param name="v">属性或是字段</param>
/// <param name="value">要设置的值</param>
/// <param name="obj">要设置的对象</param>
private void SetObjectValue(MyInfo v, object value, ref object obj)
{
string name =null;//获得字段或是属性的数据类型名称,用来给相应的数据类型赋值
#if POPRS_ //属性
name = v.PropertyType.Name;
#elif FIELDS_ //字段
name=v.FieldType.Name;
#endif
switch (name)
{
case "Int32": //int
v.SetValue(obj, int.Parse(value.ToString()));
break; ; case "String": //string
v.SetValue(obj, value.ToString());
break; case "Double": //double
v.SetValue(obj, double.Parse(value.ToString()));
break; case "Object"://object
v.SetValue(obj, value);
break; case "Boolean"://bool
v.SetValue(obj, bool.Parse(value.ToString()));
break; case "Char"://char
v.SetValue(obj, char.Parse(value.ToString()));
break; case "Byte[]"://byte[]
if(value!=DBNull.Value)
v.SetValue(obj, (byte[])value);//强转为字节数组
break; default: //其他类型,以后用的时候再加上
throw new Exception("没有指定转换的类型!!!"); }
}
11.用法
在要用的类中声明一个静态对象
public class MyApp
{
public static BDAdo<TXL_TABLE> Ado { get => new BDAdo<TXL_TABLE>();/* set => ado = value;*/ }
}
示例1:添加数据
TXL_TABLE tt = new TXL_TABLE();
tt.ID = int.Parse(txtID.Text);
tt.TName = txtName.Text;
tt.Sex = txtSex.Text;
tt.Age=int.Parse(txtAge.Text);
tt.FenZu = txtFenZu.Text;
tt.Tel = txtTel.Text;
byte[] tem = { 0 };
if (picImage.Image != null)
tt.Image = MyApp.Ado.ImageToByte(picImage.Image);
else
tt.Image = tem; bool bRet = MyApp.Ado.InsertData(tt);
if(bRet)
{
MessageBox.Show("添加成功")
}
示例2:修改数据
TXL_TABLE tt = new TXL_TABLE();
tt.ID = int.Parse(txtID.Text);
tt.TName = txtName.Text;
tt.Sex = txtSex.Text;
tt.Age=int.Parse(txtAge.Text);
tt.FenZu = txtFenZu.Text;
tt.Tel = txtTel.Text;
byte[] tem = { 0 };
if (picImage.Image != null)
tt.Image = MyApp.Ado.ImageToByte(picImage.Image);
else
tt.Image = tem; if( MyApp.Ado.UpdateData($"ID={oldID}", tt)>0)
MessageBox.Show("修改成功");
示例3:查找单个对象
int id = (int)Tag;
TXL_TABLE tt= MyApp.Ado.FindOneObject($"ID={id}");
//......
C#反射在数据库操作中的应用(反射属性,反射字段)的更多相关文章
- [转]C#反射,根据反射将数据库查询数据和实体类绑定,并未实体类赋值
本文来自:http://www.cnblogs.com/mrchenzh/archive/2010/05/31/1747937.html /****************************** ...
- C#反射获取数据库字段
static string sqlselect = "insert into {0}({1}) values ({2})"; (这个方法可以适用于任何数据库的插入语句) publi ...
- [.net 面向对象程序设计进阶] (21) 反射(Reflection)(下)设计模式中利用反射解耦
[.net 面向对象程序设计进阶] (21) 反射(Reflection)(下)设计模式中利用反射解耦 本节导读:上篇文章简单介绍了.NET面向对象中一个重要的技术反射的基本应用,它可以让我们动态的调 ...
- 反射-优化及程序集等(用委托的方式调用需要反射调用的方法(或者属性、字段),而不去使用Invoke方法)
反射-优化及程序集等(用委托的方式调用需要反射调用的方法(或者属性.字段),而不去使用Invoke方法) 创建Delegate (1).Delegate.CreateDelegate(Type, ...
- 数据库操作中如何批量执行多个sql文件?
数据库操作中如何批量执行多个sql文件? 1.应用场景:在历史数据导入过程中,会发现有很多个表形成的.sql文件,要是一个一个文件去手动执行,实在是费时间,所以采取以下方法. 2.将文件放在一定位置, ...
- 使用反射功能在Unity运行状态通过Inspector面板修改字段和调用方法
使用反射功能在Unity运行状态通过Inspector面板修改字段和调用方法 效果展示 一个很简单的组件脚本 运行状态在Inspector面板可以随便修改字段和调用方法 方法调用日志 设计由来 最近在 ...
- @Retention(保留) 此注解用于运行时候(反射)时候使用 如果不使用的话 在反射时候无法获取到注解的值
@Retention(保留) 此注解用于运行时候(反射)时候使用 如果不使用的话 在反射时候无法获取到注解的值
- 【java】java反射机制,动态获取对象的属性和对应的参数值,并属性按照字典序排序,Field.setAccessible()方法的说明【可用于微信支付 签名生成】
方法1:通过get()方法获取属性值 package com.sxd.test.controller; public class FirstCa{ private Integer num; priva ...
- Column注解的的RetentionPolicy的属性值是RUTIME,这样注解处理器可以通过反射,获取到该注解的属性值,从而去做一些运行时的逻辑处理
1.Column注解的的RetentionPolicy的属性值是RUTIME,这样注解处理器可以通过反射,获取到该注解的属性值,从而去做一些运行时的逻辑处理 2. 自定义注解: 使用@interfac ...
- SQL批量更新数据库中所有用户数据表中字段类型为tinyint为int
--SQL批量更新数据库中所有用户数据表中字段类型为tinyint为int --关键说明:--1.从系统表syscolumns中的查询所有xtype='48'的记录得到类型为[tinyint]的字段- ...
随机推荐
- nginx 添加 模块
--- title: nginx 添加 模块 date: 2019-10-31 11:21:46 categories: tags: - config - nginx --- 说明: 已经安装好的Ng ...
- 【排行榜】Carla leaderboard 排行榜 运行与参与手把手教学
此分支主要供参与leaderboard排名使用,介绍如何构建队伍,提交自己代码,此部分较为简单,主要是基本教学与演示:后续可以参考更多的开源代码进行学习等. 基本参与此榜单的大多都是学校和实验室,还是 ...
- Win10 下安装使用easyocr图片识别工具
[前言] 最近在做图像识别相关的工作,找到了一个名为EasyOCR的pythoh 库. 使用过程中出现了一些问题,现做简单记录. [正文] 1. 安装EasyOCR 我用了最简单的方法:pip3 in ...
- node.js (原生模板引擎模板)
app01 // 引入http模块 const http = require('http'); //连接数据库 require('./model/connects'); // 创建网站服务器 cons ...
- Spring PropertySource,获取指定application.properties文件
@PropertySource注解的使用 @PropeertySource,指定加载配置文件 配置文件映射到实体类 使用@Value映射到具体的java属性 CustomConfig.java pac ...
- Linux相关知识备忘(随时更新)
1.dpkg Debian Packager,Debian包管理器.可以方便的对软件进行安装更新和移除. (1)安装 dpkg -i xx.deb (2)卸载,但不删除配置文件 dpkg -r xx ...
- ASP.NET Core 程序集注入(一)
1.创建[特性]用于标注依赖注入 using Microsoft.Extensions.DependencyInjection; using System; using System.Collecti ...
- 常回家看看之largebin_attack
常回家看看之largebin_attack 先简单介绍一下什么是largebin largebin 是 glibc 的 malloc 实现中用于管理大块内存的一种数据结构.在 glibc 的内存分配中 ...
- 提高 C# 的生产力:C# 13 更新完全指南
前言 预计在 2024 年 11 月,C# 13 将与 .NET 9 一起正式发布.今年的 C# 更新主要集中在 ref struct 上进行了许多改进,并添加了许多有助于进一步提高生产力的便利功能. ...
- Python和RPA网页自动化-浏览器切换不同窗口页面
以百度为例,点击[BOSS直聘]词条会打开一个BOSS新窗口页面,分别使用Python和RPA网页自动化在不同的窗口页面来回切换窗口完成以下顺序步骤 1.Python代码如下 步骤:打开新窗口页面后, ...