ORM框架学习

Posted zxwdont

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ORM框架学习相关的知识,希望对你有一定的参考价值。

ORM框架--新增数据

今天的内容对照上一节内容,上一节内容是对数据的查询,本节主要是对数据的新增。程序入口代码如下

static void Main(string[] args)
        
            SqlHelper help = new SqlHelper();
            UserModel u1 = help.Query<UserModel>(1);
            Company com1 = help.Query<Company>(2);
            bool re1 = help.AddData(u1);
            bool re2 = help.AddData(com1);
        

AddData()方法和Query()方法一样。都是限制为where T:BaseModel的泛型方法。AddData代码如下所示

 public bool AddData<T>(T t) where T:BaseModel
        
            bool re = true;
            
            try
            
                Type type=typeof(T);
                string conStr = "Server=127.0.0.1;Database=master; integrated security=SSPI";
                string AddStr = SqlBuilder<T>.GetSql(SqlBuilder<T>.SqlType.AddSql);
                var sqlpara = type.GetProperties().FilterKey().Select(p => new SqlParameter("@" + p.GetMappingName(), p.GetValue(t) ?? DBNull.Value)).ToArray();
                using (SqlConnection conn = new SqlConnection(conStr))
                
                    SqlCommand cmd = new SqlCommand(AddStr, conn);
                    cmd.Parameters.AddRange(sqlpara);
                    conn.Open();
                    int result= cmd.ExecuteNonQuery();
                    return result > 0;
                
            
            catch (Exception ex)
            
                throw new Exception(ex.Message);
                re = false;
            
            return re;
        

1.按照特性过滤不需要实体字段

因为我们现在做的是新增,数据库设计id为自增类型,所以在insert时,我们不需要新增id字段,所以就要想办法把id字段过滤。解决的办法是通过给ID设置特性ThemeKeyAttribute,特性定义如下所示

/// <summary>
    /// 主键特性
    /// </summary>
    public class ThemeKeyAttribute:Attribute
    
    
    

在特性方法里面没有任何实现,主要目的是用来做标记。同时,我们需要为id字段添加上面定义的特性,如下所示

public class BaseModel
    
        [ThemeKeyAttribute]
        public int Id  get; set; 
    

这样一来,就把company实体和User尸体的ID字段加上了特性。我们需要在获取实体属性时,调用过滤主键方法

技术图片

 

 

Filter是一个IEnumerable类型那个的扩展方法,定义如下所示:

public static IEnumerable<PropertyInfo> FilterKey(this IEnumerable<PropertyInfo> props)
        
            return props.Where(p=>!p.IsDefined(typeof(ThemeKeyAttribute),true));
        

在Filter方法中,直接传入当前的属性集合类型,把标记有ThemeKeyAttribute的属性过滤掉后再返回集合。

在Filter方法中,我们通过方法p.IsDefined(typeof(ThemeKeyAttribute),true)就可以判断一个类型是否具有某种特性。

2.泛型缓存

由于在执行AddData()方法时,我们的sql语句结构都是类似的(insert into [tab]([]) values(‘‘)),为了提高代码执行效率,避免每次执行AddData()方法都去初始化一次sql语句,我们决定采用泛型缓存的方法,定义如下一个泛型类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Theme.Model;
using Theme.Framework;
namespace Theme.DAL

    public  class SqlBuilder<T> where T:BaseModel
    
        private static string FindSql=null;
        private static string AddSql=null;
        static SqlBuilder()
        
            
                Type t = typeof(T);
                string table = t.GetMappingName();
                string props = string.Join(",", t.GetProperties().Select(p => "[" + p.GetMappingName() + "]"));
                T ti = Activator.CreateInstance<T>();
                FindSql = string.Format("select 0 from [1] where id=@id ", props, table);
            
            
                Type type = typeof(T);
                string table = type.GetMappingName();
                string param = string.Join(",", type.GetProperties().FilterKey().Select(p => "[" + p.GetMappingName() + "]"));
                string valueStr = string.Join(",", type.GetProperties().FilterKey().Select(p => "@" + p.GetMappingName()));
                
                //id为自增的关键字,不能插入,应该把ID屏蔽
                AddSql = string.Format("insert into [0](1) values(2)", table, param, valueStr);
            
        
        public static string GetSql(SqlType sqltype)
        
            switch (sqltype)
            
                case SqlType.AddSql:
                    return AddSql;
                case SqlType.FindSql:
                    return FindSql;
                default:
                    throw new Exception("wrong sqlType");
            
        
        public enum SqlType
        
            FindSql,
            AddSql
        
    

注意,要通过技术图片限制当前类只能是继承了BaseModel父类的才能访问。我们把sql语句定义成静态字段,在每次使用该类之前,该类进行初始化生成FindSql和AddSql语句。这样确保了一个类型的对象只会初始化一次sql语句,这样就节省了多对象调用反复拼装sql语句的问题。

 

 

3.参数化sql,避免sql注入

为了避免SQL注入问题的发生,我们通过参数化的方法拼装SQL执行语句,如下图所示:

技术图片

 

 在具体执行sql语句时,添加一下各个参数的值,如下图所示:

技术图片

 

以上是关于ORM框架学习的主要内容,如果未能解决你的问题,请参考以下文章

ORM框架学习

JavaWeb学习路线

Mysql学习日记-08ORM框架(结束)

Python学习---抽屉框架分析[ORM操作]180314

学习笔记30_ORM框架

轻量级ORM框架——第一篇:Dapper快速学习