C#手写ORM框架,核心实现

23 篇文章 1 订阅
20 篇文章 0 订阅

ORM 对象关系映射,net平台上最出名就是EF框架了,当然还有dapper,EF好用的,但是他太大了,如果是一写小项目的项目则咩有必要,那么dapper是一个比较轻量级的,他的映射在于实体对象和sql参数的对应,比较接近ado.net了,那么我们可以自己写一个orm么?当然是可以的,其实不管怎么样最后到底层还是sql语句,对于net来说就是 ado.net!
1,在此之前,应该了解一写关于反射的知识!
很多时候我们的实体字段名字是和数据表字段的名字是不相同的,那么我们是通过方射实体字段的特性字段来获取的!
例如实体定义:

[Table("[User]")]
public class User
{
    [Id("UserId", IsGenerated = true)]
    public int UserId { get; set; }

    [Column("Email")] 
    public string Email { get; set; }

    [Column("CreatedTime", false)]
    public DateTime CreatedTime { get; set; }
}

特性值的定义,继承Attribute类型,我这里也出来

 public class TableAttribute : Attribute
        {
            /// <summary>
            /// 表名
            /// </summary>
            public string Name { get; private set; }
    
            public TableAttribute(string name)
            {
                this.Name = name;
            }
        }
public class ColumnAttribute : Attribute
{
    /// <summary>
    /// 是否为数据库自动生成
    /// </summary>
    public bool IsGenerated { get; set; }
    /// <summary>
    /// 列名
    /// </summary>
    public string Name { get; set; }

    public ColumnAttribute(string name)
    {
        this.Name = name;
        this.IsMapping = true;
    }
    public bool IsMapping { get; set; }
    public ColumnAttribute(string name, bool IsMapping)
    {
        this.Name = name;
        this.IsMapping = IsMapping;
    }

接下来简答的写了一个插入数据库方法

 public class DBorm<T> where T : class
    {
        private static string connectionString = "";  //链接字符串

        public static int InsertEntity<T>(T Entity) 
    {
        var type = typeof(T);
        Dictionary<string, object> parameters = new Dictionary<string, object>();
        var properties = type.GetProperties();   //通过反射的方式获取到了 特性

        string tableName = string.Empty;
        TableAttribute[] tableAttrs = (TableAttribute[])typeof(User).GetCustomAttributes(typeof(TableAttribute), true);
        if (tableAttrs.Length > 0)
        {
            tableName = tableAttrs[0].TableName;
        }
        else
        {
            tableName = type.Name;  //特性中的名字,
        }

        /*将所有的列放到集合里*/
        List<ColumnAttribute> columns = new List<ColumnAttribute>();
        for (int i = 0; i < properties.Length; i++)
        {
            var pi = properties[i];
            var attrs = (ColumnAttribute[])pi.GetCustomAttributes(typeof(ColumnAttribute), true);
            if (attrs.Length > 0)
            {
                columns.Add(attrs[0]);
            }
        }
       
       //构造sql语句
        StringBuilder sql = new StringBuilder();
        sql.Append("INSERT INTO [").Append(tableName).Append("](");
        int paramIndex = 0;

        for (int i = 0; i < properties.Length; i++)
        {
            var pi = properties[i];
            var attrs = (ColumnAttribute[])pi.GetCustomAttributes(typeof(ColumnAttribute), true);
            if (attrs.Length > 0 && attrs[0].IsGenerated == false && attrs[0].IsMapping == true)
            {
                if (paramIndex > 0)
                    sql.Append(",");

                sql.Append(attrs[0].Name);
                paramIndex++;
            }
        }

        sql.Append(") VALUES (");
        paramIndex = 0;
        for (int i = 0; i < properties.Length; i++)
        {
            var pi = properties[i];
            var attrs = (ColumnAttribute[])pi.GetCustomAttributes(typeof(ColumnAttribute), true);
            if (attrs.Length > 0 && attrs[0].IsGenerated == false && attrs[0].IsMapping == true)
            {
                if (paramIndex > 0)
                    sql.Append(",");

                sql.Append("@p").Append(paramIndex);
                parameters.Add("@p" + paramIndex, pi.GetValue(Entity, null));
                paramIndex++;
            }
        }

        sql.Append(")");

        SqlConnection conn = new SqlConnection(connectionString);
        var cmd = conn.CreateCommand();
        cmd.CommandText = sql.ToString();
        foreach (var item in parameters)
        {
            var pa = cmd.CreateParameter();
            pa.ParameterName = item.Key;
            pa.Value = item.Value ?? DBNull.Value;
            cmd.Parameters.Add(pa);
        }

        conn.Open();
        return cmd.ExecuteNonQuery();

    }
}

简单看一下,是很简单的,很快就是实现了通过反射实现了ORM的操作,平时工作比较忙,只能快速的把一些核心的东西写下来,当然自己写过一套比较完整的ORM框架,后面有时间写,欢迎指点!

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C#中,常见的ORM框架有Entity Framework、NHibernate、Dapper等,这里以Entity Framework为例,介绍如何访问SQL Server实例。 1. 安装Entity Framework 首先,需要在Visual Studio中安装Entity Framework。打开NuGet包管理器控制台,执行以下命令: ``` Install-Package EntityFramework ``` 2. 配置连接字符串 在App.config或Web.config文件中,需要配置SQL Server数据库的连接字符串,例如: ``` <connectionStrings> <add name="MyDbContext" connectionString="Data Source=localhost;Initial Catalog=test;User ID=root;Password=123456;MultipleActiveResultSets=True;" providerName="System.Data.SqlClient" /> </connectionStrings> ``` 其中,`Data Source`指定了SQL Server实例的主机名,`Initial Catalog`指定了数据库名称,`User ID`和`Password`分别为数据库用户名和密码。 3. 创建实体类 使用Entity Framework需要创建实体类,实体类映射到数据库中的表。例如: ``` public class User { public int Id { get; set; } public string Name { get; set; } public int Age { get; set; } } ``` 其中,`Id`属性为主键,类型为int,`Name`和`Age`属性分别为姓名和年龄,类型为string和int。 4. 创建DbContext类 使用Entity Framework需要创建DbContext类,DbContext类表示数据库上下文,包含了所有实体类与数据库表之间的映射关系。例如: ``` public class MyDbContext : DbContext { public DbSet<User> Users { get; set; } public MyDbContext() : base("name=MyDbContext") { } } ``` 其中,`DbSet`表示一个实体集,`Users`属性表示User实体类对应的数据库表。`MyDbContext`类继承自`DbContext`类,调用基类的构造函数时,传入连接字符串的名称。 5. 使用DbContext进行数据库操作 在C#代码中,可以使用DbContext对象进行数据库操作,例如: ``` using (var db = new MyDbContext()) { var user = new User { Name = "张三", Age = 20 }; db.Users.Add(user); db.SaveChanges(); } ``` 使用`using`语句创建`MyDbContext`对象,然后创建`User`对象并添加到`Users`属性中,最后调用`SaveChanges`方法提交更改。Entity Framework会自动将实体类与数据库表之间的映射关系转换为SQL语句,执行数据库操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值