C# 利用自定义特性,动态拼接sql,查询数据库,动态新增datagridview 列

之前在给一个工厂客户开发一套"售后包装防错系统"的时候,由于业务比较复杂,

每个表的字段基本都保持在10-20个字段区间,如下截图(可向右滑动滚动条)

正常的做法,肯定是一顿卡卡操作,新建列,编辑列,一个一个的去写 name,DataPropertyName, HeaderText....

字段少的时候,我也比较喜欢这种方式,无脑开发最爽了。但是转念一想,老子的时间很宝贵啊,家里娃还在床上哭呢,我得去抱娃。

有没有更快速,便捷的方法呢?要不说人类进步的一大原因就是人懒呢,能做一步,绝不做两步。

好了,废话不多说,直接先说思路,再上代码,大佬嘛,就请要么走开,要么嘴下留情。

文中展示的代码,目的只是为了显示这么一个思路逻辑,至于优美不优美,牛逼不牛逼啥的,咱也就不要太计较了。

我们先解决下面这些问题:

1:这个类对象中的字段属性能不能不要我一个一个的去写

2:sql语句中的queryColumn能不能不要我一个一个去写

3:这datagridview列能不能动态添加,我也不想去写

你瞅瞅,你这要求这么多,还不值得点上一根烟,好好的思考下为什么吗?

好了,我们一个问题一个问题的解决和上代码

1:这个类对象的字段属性值,可以通过

复制代码
select column_name from INFORMATION_SCHEMA.COLUMNs
where table_name='P_BMWDetailBom'

去查询数据库,找到表中的字段集合,我这里没有做这样的操作,诸君请自行脑补。

2:结合第二,第三个问题,我在类对象里 加了一个自定义特性 ,来标记 某个属性是否需要拼接到sql中,是否需要显示在datagridview列中,并且显示的HeaderText 是啥,然后再通过反射,获取到对应的属性和特性,由此动态的去获取数据库列,拼接sql,添加datagridview列。

一:自定义特性

cs 复制代码
 public class ChangeShow : Attribute
 {
     /// <summary>
     /// 是否需要查询
     /// 显示
     /// </summary>
     public bool Value { get; private set; }
     /// <summary>
     /// 显示的text
     /// </summary>
     public string TextStr { get; private set; }
     public ChangeShow(bool value,string textStr)
     {
         Value = value;
         TextStr = textStr;
     }
 }

二:类对象属性上标记特性

cs 复制代码
   [Serializable]
public class P_BMWDetailBom
 {
       public int Id { get; set; }
     [ChangeShow(true, "长城零件号")]
     public string GWMPartCode { get; set; }
     [ChangeShow(true, "BMW11位零件号")]
     public string BWMPartCode11Bit { get; set; }
     [ChangeShow(true, "中文零件描述")]
     public string PartCodeName { get; set; }

三:Form界面 绑定datagridview集合

cs 复制代码
 private void Test_Load(object sender, EventArgs e)
 {
     ///待查询的queryColumns列集合
     List<string> queryColumns = new List<string>();
     // 获取类的属性描述
     // 获取类型信息
     Type type = typeof(P_BMWDetailBom);

     // 遍历所有属性
     foreach (var property in type.GetProperties())
     {
         // 获取属性上的自定义Attribute
         var attributes = property.GetCustomAttributes(typeof(ChangeShow), true);
         foreach (ChangeShow attribute in attributes)
         {
             if (attribute.Value) {
                 queryColumns.Add(property.Name);
                 // 创建新列
                 DataGridViewColumn newColumn = new DataGridViewTextBoxColumn(); 
                 // 设置新列的属性
                 newColumn.HeaderText = attribute.TextStr;
                 newColumn.Name = property.Name;
                 // 根据需要设置其他属性,例如 newColumn.ValueType = typeof(int);
                 newColumn.DataPropertyName = property.Name;
                 // 将新列添加到DataGridView中
                 dataGridView1.Columns.Add(newColumn); 
             }
         }
     }

     //查询数据库
     BMWDetailBomBll bll = new BMWDetailBomBll();
     DataTable dt = bll.pageData(queryColumns, pageIndex, pageSize);
     this.dataGridView1.DataSource = dt;
     string dddd = "";

 }

四:Dal层 查询语句拼接,各位可以根据自己的需要,自行按照个人喜好处理

cs 复制代码
 public DataTable pageData(List<string> queryColumns, int pageIndex, int pageSize)
 {
     if (queryColumns != null && queryColumns.Count > 0)
     {
         StringBuilder stringBuilder = new StringBuilder();
         stringBuilder.Append("select ");
         foreach (string key in queryColumns)
         {
             stringBuilder.Append("a.");
             stringBuilder.Append(key);
             stringBuilder.Append(",");
         }
         string querySql = stringBuilder.ToString().TrimEnd(',');
         stringBuilder.Clear();
         stringBuilder.Append(querySql);
         stringBuilder.Append(" from (select Row_number() over(order by id desc) as rownum,* from P_BMWDetailBom where 1=1  ) a where a.rownum between ");
         stringBuilder.Append(((pageIndex - 1) * pageSize + 1));
         stringBuilder.Append(" and  ");
         stringBuilder.Append(pageSize * pageIndex);
         DataSet ds = SqlUtil.ExecuteQuery(stringBuilder.ToString(), null);
         return ds.Tables[0];
     }
     else
         return null;
   
 }

最终测试结果

相关推荐
HackTwoHub9 小时前
AI大模型网关存在SQL注入、附 POC 复现、影响版本LiteLLM 1.81.16~1.83.7(CVE-2026-42208)
数据库·人工智能·sql·网络安全·系统安全·网络攻击模型·安全架构
l1t9 小时前
DeepSeek总结的DuckLake构建基于 SQL 原生表格式的下一代数据湖仓
数据库·sql
KmSH8umpK9 小时前
Redis分布式锁从原生手写到Redisson高阶落地,附线上死锁复盘优化方案进阶第八篇
数据库·redis·分布式
TDengine (老段)10 小时前
从施工监测到运营预警,桥科院用 TDengine 提升桥梁数据管理能力
大数据·数据库·物联网·时序数据库·tdengine·涛思数据
S1998_1997111609•X11 小时前
论mysql国盾shell-sfa犯罪行为集团下的分项工程及反向注入原理尐深度纳米算法下的鐌檵鄐鉎行为
网络·数据库·网络协议·百度·开闭原则
KmSH8umpK12 小时前
Redis分布式锁从原生手写到Redisson高阶落地,附线上死锁复盘优化方案进阶第七篇
数据库·redis·分布式
yaodong51813 小时前
不会Python也能数据分析:Gemini 3.1 Pro解决办公问题的SQL自动生成
python·sql·数据分析
BU摆烂会噶13 小时前
【LangGraph】持久化实现的三大能力——时间旅行
数据库·人工智能·python·postgresql·langchain
l1t14 小时前
DeepSeek总结的DuckLake 入门
数据库
Joseph Cooper14 小时前
RAG 与 AI Agent:智能体真的需要检索增强生成吗?
数据库·人工智能·ai·agent·rag·上下文工程