0. Preface
In the previous articles, we learned how to access the database, modify and add new data. How to obtain data through DataSet and DataAdapter, we will try to implement a simple ORM framework or ORM tool class by ourselves in this article.
Knowledge points involved:
- Reflection (primary)
- Already have knowledge
1. ORM
So, the question is, what is ORM? The full name of ORM is Object Relational Mapping, which is translated as object relational mapping. It is a technology that saves objects into a database by describing the mapping relationship between objects and databases.
In C#, the Entity Framework once shines, covering the glory of other ORM frameworks (even nowadays).
Later, in addition to some other ORM frameworks gradually emerged, further enriching the market. Therefore, there are probably the following types that are more popular:
- Dapper A lightweight ORM framework
- Entity Framework/Entity Framework Core Fully Functional Framework
- Nhibernate The famous .net version of Hibernate on the Java platform
- etc.
Well, these are a few frameworks that the creative team I found recently are still updating, and of course there are many other interesting and useful ORM frameworks. Everyone is welcome to add.
The main purpose of this article is not to introduce these frameworks (this is the content in the future), but to understand the underlying core by implementing an ORM-like framework ourselves.
2. Design
Let’s first analyze what functions should we have if we design a tool class that converts between an entity object and a database?
- Mapping relationship between an attribute and a database field
- SQL template for adding, deleting, modifying and checking
- Conversion of query results and objects
3. Implementation
First, declare a class. Because it cannot only support one type, all database-related methods of this class are generic methods, or this class is a generic class, so it is defined as a generic class:
public class OrmUtil<T> { }
We agreed in advance that the class name is the table name and the attribute name is the table column name, so we can quickly get the following content:
/// <summary> ///T type instance/// </summary> private Type dType; /// <summary> /// T's attribute table/// </summary> private PropertyInfo[] properties; public OrmUtil() { dType = typeof(T); properties = (); }
Declare a database connection:
public SqlConnection Connection { get; set; }
Create a private method to check if the connection is available:
/// <summary> /// Check if the connection is available/// </summary> /// <returns></returns> private bool CheckConnection() { return Connection?.State == ; }
Prepare to complete, and then start writing specific business methods:
Insert:
public int Insert(T entity) { if (!CheckConnection()) return -1;// Check the status var insert = $"insert into {}({(",", (t => ))})"; var values = (p => (entity)); var commandText = $"{insert} values('{("','", values)}')"; var command = (); = commandText; var result = (); return result; }
First splice SQL according to the mapping between the attribute name and the column name, and then execute the SQL command.
Update:
public int Update(T entity,string keyName,object keyValue) { if (!CheckConnection()) return -1; var setValues = (p => , p => $"'{(entity)}'"); var setSql = (",", (pair=>$"{}='{}'")); var sql = $"update {} set {setSql} where {keyName} = '{keyValue}'"; var command = (); = sql; return (); }
What you need to pay attention to in Update is how to correctly splice and assign SQL.
Delete:
Delete objects that meet the criteria:
public int Delete(T entity) { if (!CheckConnection()) return -1; var querySet = (p => $"{} = '{(entity)}'"); var sql = $"delete from {} where {(" and ", querySet)}"; var command = (); = sql; return (); }
The writing method here is sometimes different depending on the actual business. In most cases, the elements corresponding to the primary key are deleted, or all elements that meet a certain condition. I just gave a demonstration here, friends can try to modify it yourself.
Search:
First create a tool method to convert from DataTable to an object:
private List<T> Convert(DataTable table) { var list = new List<T>();//Declare the capacity in advance foreach(DataRow row in ()) { T entity = <T>(); foreach(var p in properties) { if (!()) continue;// If the attribute name is not in the table, ignore (entity, row[]); } (entity); } return list; }
OK, let's write a query method:
public List<T> SearchAll() { var adapter = new SqlDataAdapter($"select * from {}", Connection); var set = new DataSet(); (set); return Convert([0]); }
Such a simple ORM framework has become a prototype. Of course, the underlying ORM is actually more complicated than this. Because it needs to support different databases, Connection cannot be simply a SqlConnection, or the underlying layer is not using DataTable like we do.
In fact, the conversion from DataTable to class objects is a little more complicated than what I wrote, because it also requires determining whether this property is readable and writable.
4. Summary
Here I made a brick-and-shooting and led my friends to conceive a simple ORM framework, which also gave everyone a certain impression of it. Well, that's all for today. At the same time, it came to an end, and the next step was to go to the Entity Framework. Of course, the two classes DataSet and DataAdapter have not been finished. This part of the content may be completed in subsequent extra chapters.
The above is the detailed content of how to implement an ORM by yourself in c#. For more information about implementing an ORM by c#, please pay attention to my other related articles!