C#反射,特性,数据库结合使用

这篇博客展示了如何在C#中结合反射和特性来操作数据库。通过自定义DBTableName和DBField特性,实现从类到数据表的映射,并在BaseBLL泛型类中使用反射获取数据。示例中,Student和StudentMsg类被映射到相应的数据库表,通过GetModelByID方法查询数据并打印结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

using System;
using System.Reflection;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;

namespace ConsoleApplication1
{
    //View
    class Program
    {
        static void Main(string[] args)
        {
            StudentBll studentBll = new StudentBll();
            Student model = studentBll.GetModelByID("3");

            Console.WriteLine(model.ID + " " + model.Name + "    " + model.Age);
            StudentMsgBll studentMsgBll = new StudentMsgBll();
            StudentMsg modelMsg = studentMsgBll.GetModelByID("1");

            Console.WriteLine(modelMsg.Id + " " + modelMsg.StuName + "    " + modelMsg.Age+"    "+modelMsg.Address);
            Console.WriteLine("请按下键盘任意键退出!");
            Console.ReadKey();
        }
    }
    //model
    [DBTableName("DBMyTest")]
    public class Student
    {
        [DBField(true)]//调用DBField的有参构造函数,true说明是主键
        public int ID { get; set; }
        [DBField]//调用DBField的无参构造函数,默认不是主键
        public string Name { get; set; }
        [DBField]
        public int Age { get; set; }
    }
    [DBTableName("DBMyTest")]
    public class StudentMsg
    {
        [DBField(true)]
        public int Id { get; set; }
        [DBField]
        public string StuName { get; set; }
        [DBField]
        public int Age { get; set; }
        [DBField]
        public string Address { get; set; }
    }
    //control
    public class StudentBll : BaseBLL<Student>
    {
    }
    public class StudentMsgBll : BaseBLL<StudentMsg>
    {
    }
    //BaseBLL
    public class BaseBLL<T> where T : class,new()//定义泛型类,T约束为引用类型和必须有一个无参构造函数
    {
        public virtual T GetModelByID(string ID)//虚方法,方便以后派生类用override
        {
            try
            {
                T model = null;
                model = Activator.CreateInstance<T>();
                PropertyInfo[] _PropertyInfo = model.GetType().GetProperties();

                string TableName = model.GetType().Name;//得到类的名称,作为数据表名。

                if (_PropertyInfo == null) return null;
                else
                {
                    DBTableNameAttribute _DBTableNameAttribute = model.GetType().GetCustomAttribute<DBTableNameAttribute>();
                    string _ConnectionString = _DBTableNameAttribute._DBConnection;//获取model类特性标志的数据库连接字符串

                    using (SqlConnection con = new SqlConnection(_ConnectionString))
                    {
                        con.Open();

                        string SelectCommand = "select * from "+TableName+" where ID=";

                        foreach (PropertyInfo p in _PropertyInfo)
                        {
                            if (p.GetCustomAttribute<DBField>().GetIsID)//根据属性(property)的特性获取ID
                            {
                                SelectCommand += ID;
                                break;
                            }
                        }

                        SqlDataAdapter _SqlDataAdapter = new SqlDataAdapter(SelectCommand, con);
                        DataSet _DataSet = new DataSet();
                        _SqlDataAdapter.Fill(_DataSet);
                        if (_DataSet.Tables[0].Rows.Count > 0)
                        {
                            DataRow _DataRow=_DataSet.Tables[0].Rows[0];
                            foreach(PropertyInfo p in _PropertyInfo)
                            {
                                p.SetValue(model,_DataRow[p.Name]);
                            }
                            return model;//这里没什么好说的,用的是ADO.NET数据库访问
                        }
                        else return null;
                    }
                }
            }
            catch
            {
                return null;
            }
        }
    }
    //Attribute
    [AttributeUsage(AttributeTargets.Class, AllowMultiple=false, Inherited=false)]
    public class DBTableNameAttribute : Attribute
    {
        public string _DBTableName { get; set; }//数据表名
        public string _DBConnection { get; set; }
        public DBTableNameAttribute(string DBConnection)
        {
            _DBConnection = ConfigurationSettings.AppSettings.Get(DBConnection);//读取配置里面的数据库连接字符串
        }
    }
    [AttributeUsage(AttributeTargets.Property,AllowMultiple=false,Inherited=false)]
    public class DBField:Attribute
    {
        private bool _IsID = false;//默认不是主键
        public DBField()
        {
        }
        public DBField(bool IsID) 
        {
            _IsID = IsID;
        }
        public bool GetIsID 
        {
            get { return _IsID; }
        }
    }
}
数据表结构如下:
USE [MyTest]
GO

/****** Object:  Table [dbo].[Student]    Script Date: 2016/4/25 15:17:12 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[Student](
	[ID] [int] IDENTITY(1,1) NOT NULL,
	[Name] [nvarchar](50) NULL,
	[Age] [int] NULL,
 CONSTRAINT [PK_Student] PRIMARY KEY CLUSTERED 
(
	[ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

USE [MyTest]
GO

/****** Object:  Table [dbo].[StudentMsg]    Script Date: 2016/4/25 15:18:06 ******/
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[StudentMsg](
	[Id] [int] IDENTITY(1,1) NOT NULL,
	[StuName] [nvarchar](50) NOT NULL,
	[Age] [int] NULL,
	[Address] [nvarchar](200) NULL,
 CONSTRAINT [PK_StudentMsg] PRIMARY KEY CLUSTERED 
(
	[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO
控制台app.config配置
<appSettings>
    <add key="DBMyTest" value="Data Source=.;Initial Catalog=MyTest;Integrated Security=True"/>
  </appSettings>


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值