Try handwriting orm framework

Preface:

    In using a variety of orm framework of the process, I never get to know the rookie of the underlying implementation technology, recently just nothing to find some video and data to understand a little fur, would like to record, we do not spray.

    Called ORM (Object Relational Mapping) object-relational mapping by using the official explanation metadata mapping between objects and description databases, object-oriented programming object automatically persisted to a relational database.

    Personal understanding is to help a class of database access, it allows us to do handwriting sql, complete access to the database

    Technique used: generics, reflection characteristics, expanded

Groping steps:

step1

 New projects, build several libraries, the familiar three.

step2:

 Create a data access layer class sqlhelper;

 2.1 The method of adding a data query, also need to add the model layer SYSUSER added, to complete the mapping entity table, codes are as follows

 1  public class SysUser
 2 {
 3         public long Id { get; set; }
 4         public string Login_Name { get; set; }
 5         public string Name { get; set; }
 6         public string Icon { get; set; }
 7         public string Password { get; set; }
 8         public string Salt { get; set; }
 9         public string Tel { get; set; }
10         public string Email { get; set; }
11         public SByte Locked { get; set; }
12         public DateTime Create_Date { get; set; }
13         public long Create_By { get; set; }
14         public DateTime Update_Date { get; set; }
15         public long Update_By { get; set; }
16         public string Remarks { get; set; }
17         public SByte Del_Flag { get; set; }
18  }
View Code
 1  public SysUser QueryUser(string id)
 2   {
 3             Type type = typeof(SysUser);
 4             SysUser sysUser = new SysUser();
 5             using (var con = new MySqlConnection(strConnection))
 6             {
 7                 con.Open();
 8                 string strSql = $"select Id,Login_Name,nick_name,Icon,Password,Salt,Tel,Email,Locked,Create_Date,Create_By,Update_Date,Update_By,Remarks,Del_Flag from sys_user wherer id={id}";
 9                 MySqlCommand sqlCommand = new MySqlCommand(strSql, con);
10 
11                 MySqlDataReader mySqlDataReader = sqlCommand.ExecuteReader();
12 
13                 if(mySqlDataReader.Read())
14                 {
15                     if (mySqlDataReader.Read())
16                     {
17                         foreach (var item in type.GetProperties())
18                         {
19                             item.SetValue(sysUser, mySqlDataReader[item.Name] is DBNull ? null : mySqlDataReader[item.Name]);
20                         } 
21                     }
22                    
23                 }
24 
25             }
26 
27             return sysUser;
28  }
View Code

 2.2 The code table only for a query, the query may be required for different tables use the generic

 a. complete reflection of the splicing dynamic sql

Type type=typeof(T);
string tableNam=type.Name;
string colums=string.join(",",type.GetProperties().Select(p=>$"{p.Name}"));
string strSql = $"select {colums} from {tableName}  where id={id}";

b.ado.net complete database query

c. Data reflecting complete dynamic binding

e. the type of treatment may be null

Implementation code

. 1   public T QueryById <T> ( String ID)
 2    {
 . 3              the Type type = typeof (T);
 . 4  
. 5              T T = the Activator.CreateInstance <T> (); // Create entities 
. 6              String tableName = type.name;
 . 7              String = colums String .join ( " , " , type.GetProperties () the Select (P => $. " {} p.Name " )); // splicing query field 
. 8  
. 9              the using ( var CON = new new MySqlConnection(strConnection))
10             {
11                 con.Open();
12                 string strSql = $"select {colums} from {tableName}  where id={id}";
13 
14                 MySqlCommand sqlCommand = new MySqlCommand(strSql, con);
15                 MySqlDataReader mySqlDataReader = sqlCommand.ExecuteReader();
16 
17                 if (mySqlDataReader.Read())
18                 {
19                     foreach (var item in type.GetProperties())
20                     {
21                         item.SetValue(t, mySqlDataReader[item.Name] is DBNull ? null : mySqlDataReader[item.Name]);//需要添加Null 判断
22                     }
23                     return t;
24                 }
25                 else
26                 {
27                     return default(T);
28                 }
29             }
30 }
View Code

 Problems: the entity class name is inconsistent with the database table name, the name of the entity attributes are inconsistent with the data Table Field Name 

 May be used to solve two problems above characteristics ( explained: characteristic is essentially a class, directly or indirectly Attribute inheritance is a feature that provides the associated additional information for the target element, and the reflection at runtime manner to obtain additional information )

 Related code is as follows

 Abstract class

 1  public abstract class AbstractMappingAttribute: Attribute
 2  {
 3         private string _mappingName;
 4 
 5         public AbstractMappingAttribute(string mappingName)
 6         {
 7             this._mappingName = mappingName;
 8         }
 9 
10         public string GetMappingName()
11         {
12             return this._mappingName;
13         }
14   }
View Code

Inconsistent entity class name and table name 

1  [AttributeUsage(AttributeTargets.Class)]
2   public class MappingTableAttribute : AbstractMappingAttribute
3  {
4         public MappingTableAttribute(string tableName) : base(tableName)
5         {
6 
7         }
8  }
View Code

Inconsistent entity attributes Field 

1  [AttributeUsage(AttributeTargets.Property)]
2  public class MappingColumAttribute : AbstractMappingAttribute
3  {
4         public MappingColumAttribute(string colName) : base(colName)
5         {
6 
7         }
8  }
View Code

Note: the use of features shall be added to the present action type characteristic range, is simple to understand with class or above class properties or behavior.

Use custom entity class codes following characteristics

 1     [MappingTableAttribute("sys_user")]
 2     public class SysUser
 3     {
 4         public long Id { get; set; }
 5         public string Login_Name { get; set; }
 6         [MappingColumAttribute("nick_name")]
 7         public string Name { get; set; }
 8         public string Icon { get; set; }
 9         public string Password { get; set; }
10         public string Salt { get; set; }
11         public string Tel { get; set; }
12         public string Email { get; set; }
13         public SByte Locked { get; set; }
14         public DateTime Create_Date { get; set; }
15         public long Create_By { get; set; }
16         public DateTime Update_Date { get; set; }
17         public long Update_By { get; set; }
18         public string Remarks { get; set; }
19         public SByte Del_Flag { get; set; }
20     }
View Code

 How to get information to customize the characteristics of an entity described? 

  There is need to use extension methods

 1  public static class MappingAttributeExtend
 2 {
 3         public static string GetMappingName<T>(this T t) where T : MemberInfo
 4         {
 5             if (t.IsDefined(typeof(AbstractMappingAttribute), true))
 6             {
 7                 AbstractMappingAttribute abstractMappingAttribute = t.GetCustomAttribute<AbstractMappingAttribute>();
 8                 return abstractMappingAttribute.GetMappingName();
 9             }
10             else
11             {
12                 return t.Name;
13             }
14         }
15 }
View Code

 2.2 2.3 After a final optimization step follows the general query method code

 1 public T QueryById<T>(string id)
 2  {
 3             Type type = typeof(T);
 4 
 5             T t = Activator.CreateInstance<T>();//创建实体
 6             string tableName = type.GetMappingName();
 7             string colums = string.Join(",", type.GetProperties().Select(p => $"{p.GetMappingName()}"));//拼接查询字段
 8 
 9             using (var con = new MySqlConnection(strConnection))
10             {
11                 con.Open();
12                 string strSql = $"select {colums} from {tableName}  where id={id}";
13 
14                 MySqlCommand sqlCommand = new MySqlCommand(strSql, con);
15                 MySqlDataReader mySqlDataReader = sqlCommand.ExecuteReader();
16 
17                 if (mySqlDataReader.Read())
18                 {
19                     foreach (var item in type.GetProperties())
20                     {
21                         item.SetValue(t, mySqlDataReader[item.GetMappingName()] is DBNull ? null : mySqlDataReader[item.GetMappingName()]);
22                     }
23                     return t;
24                 }
25                 else
26                 {
27                     return default(T);
28                 }
29             }
30  }
View Code

step3:

Complete a simple query, add very much the same codes are as follows

 1 public bool Insert<T>(T t)
 2  {
 3             Type type = typeof(T);
 4 
 5             string table = type.GetMappingName();
 6             string colum = string.Join(",", type.GetProperties().Select(p => $"{p.GetMappingName()}"));
 7             string value = string.Join(",", type.GetProperties().Select(p => $"'{p.GetValue(t)}'"));
 8 
 9             using (var con = new MySqlConnection(strConnection))
10             {
11                 con.Open();
12                 string strSql = $"Insert into {table} ({colum}) values ({value}) ";
13 
14                 MySqlCommand mySqlCommand = new MySqlCommand(strSql, con);
15 
16                 return mySqlCommand.ExecuteNonQuery() == 1;
17             }
18 
19  }
View Code

 

Guess you like

Origin www.cnblogs.com/wktang/p/12231886.html