Object relationship mapping, by pure hand hit, is a super tedious and kind of coolie live, even if it can give you high efficiency, but also loss of development efficiency.
C # in the NETFramework has actually provided an ORM framework, called the Entity Framework, this framework has actually done a good job, but the framework is too heavy, to write the code in the configuration is not so good computer running on all cotton.
So we decided to write a framework of our own, one that weighs less, and secondly, is to explore the way to see how the ORM framework is actually done.
Of course, I can not make a building by myself, but we could learn from it, especially in the era of the Internet so advanced, to GitHub to see other open source code on the OK.
One, reflection.
The first thing we need to solve is when we take the value out of the database and how to assign it directly to the property of the corresponding object, we remember that the traditional approach is
Dt. rows[i]["ID"]
So a field to write, hit the field more table, it will play for half a day.
Reflection is to get the name of the variable for the class, and then assign it to the variable:
The code is as follows |
Copy Code |
Public list<t> execselect<t> (string sqlCmd) where T:new () { list<t> list = new list<t> (); DataTable dt = Select (SQLCMD); if (dt. Rows.Count = 0) { return list; } Propertyinfo[] Properties = reflectionhelper.getproperties (new T (). GetType ()); for (int i=0;i<dt. rows.count;i++) { t entity = new T (); foreach (PropertyInfo property in properties) { String Name = property. Name; Reflectionhelper.setpropertyvalue (Entity, property, dt. Rows[i][name]); } List. ADD (entity); } return list; } |
The above t is a generic type, as to what the generics are, their own Baidu.
The GetProperties function is the method that the generic uses to get the variables of the class, and it has some parameters, including getting the variables public and so on:
The code is as follows |
Copy Code |
public static propertyinfo[] GetProperties (type type) { return type. GetProperties (BindingFlags.Public | BindingFlags.Instance); }
|
Second, Value.
Now that we've got the properties of the class through GetProperties, it's better to assign the value directly through SetValue, and the problem is that if the value we take out of the database doesn't match it, we need to convert the value type.
The code is as follows |
Copy Code |
if (convert.isdbnull (value) | | (value = = null)) { return null; } String typeName = type. Fullname.tostring (); System.Console.WriteLine (TypeName); if (type = = typeof (System.nullable<uint16>)) { Value = convert.touint16 (value); } else if (type = = typeof (System.nullable<uint32>)) { Value = Convert.touint32 (value); } else if (type = = typeof (System.nullable<uint64>)) { Value = Convert.touint64 (value); } else if (type = = typeof (System.nullable<int32>)) { Value = Convert.ToInt32 (value); } else if (type = = typeof (System.nullable<int64>)) { Value = Convert.toint64 (value); } Switch (typeName) { Case "System.String": if (!isnullorempty (value)) Value = value. ToString (); Break Case "System.Boolean": if (!isnullorempty (value)) Value = Convert.toboolean (value); Break Case "System.Int16": if (!isnullorempty (value)) Value = convert.toint16 (value); Break Case "System.Int32": if (!isnullorempty (value)) Value = Convert.ToInt32 (value); Break Case "System.Int64": if (!isnullorempty (value)) Value = Convert.toint64 (value); Break Case "System.Double": if (!isnullorempty (value)) Value = convert.todouble (value); Break Case "System.float": if (!isnullorempty (value)) Value = convert.todouble (value); Break Case "System.Single": if (!isnullorempty (value)) Value = convert.todouble (value); Break Case "System.Decimal": if (!isnullorempty (value)) Value = Convert.todecimal (value); Break Case "System.DateTime": if (!isnullorempty (value)) Value = Convert.todatetime (value); Break } return value; } |
Third, reflection and dynamic compilation.
Reflection really is a good thing, but net4.0 will have a better thing: dynamic, to know that reflection is actually very efficient, but dynamically compiled will be much faster, if you do not understand dynamic, then the following example will tell you the difference between the two:
public void Test ()
{
SomeClass C = new SomeClass ();
PropertyInfo property = C.gettype (). GetProperties () [0];
Starttest ("Begin reflection.");
for (int i = 0; i < 1000000; i++)
{
Property. SetValue (c, I, NULL);
}
Endtest ("End Reflection");
Idynamicpropertyinfo dproperty = new DynamicType (C.gettype ()). GetProperties () [0];
Starttest ("Begin dynamic.");
for (int i = 0; i < 1000000; i++)
{
Dproperty. SetValue (c, I, NULL);
}
Endtest ("End dynamic");
}
So what's the difference between the two:
--test started:assembly:pixysoft.framework.reflection.dll--
Begin reflection.
End Reflection
00:00:09.0625000
Begin dynamic.
End Dynamic
00:00:00.0468750
The difference is too far, so if you feel that your program is slowing down because of reflection, try dynamic compilation.