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框架,后面有时间写,欢迎指点!