Development NOTE 1: model, Development Note Model
ORM implementation includes Reflection, fan type, code generation, and other common methods, such as single-use or hybrid.
The c # model is very powerful. When used in ORM, some features may become more important.
At the beginning of implementation, I tried to write the code as An ORM base class.
Namespace Coat {public class ORMBase <T> where T: class {... public bool Update () {using (var conn = OpenConnection () {// Beblow compile error, because conn. update <T> exact CT parameter to be T // I. e. the sub-class, but "this" is parent class. return conn. update <T> (this) ;}}// the code generated by the subclass is similar to: public class User: ORMBase <User> {...}
The intent is to implement common methods such as adding, deleting, modifying, and querying ActiveRecord objects in the base class, which is more concise than using code generation in a specific subclass. Besides, editing an actual type is easier than editing a template.
I think c #class User: ORMBase<User> {
This type declaration is very powerful.
The User type is inherited from ORMBase, while the ORMBase type uses the User type as the fan type parameter. Is there a circular dependency?
In this way, ORMBase can use the Model T for various programming.
The above code is stuckconn.Update<T>(this);
This statement is called.
Because dapper's Update method signature is similarUpdate<T>(T entityToUpdate)
, Which I wrote in ORMBasethis
Is the parent class, that is, ORMBase; and The type parameter T passed to the Update is a subclass, such as User.
The compiler directly reports an error.
ORMBase and T are two different types and cannot be directly converted.conn.Update<T>((T)this);
The compiler also reports an error.
Some colleagues suggested modifying the ORMBase Update signaturepublic bool Update(T obj)
And then pass obj instead of this to dapper.
This can solve the compilation problem, but it will make the application call time troublesome. It is better to directly generate the Update method in the subclass, but it is still not beautiful.
I studied some fan constraints and found a more beautiful way.
ORMBase and T cannot be converted to each other because the compiler does not know the inheritance relationship between them, so it can be converted by writing their inheritance relationship to the model constraints.
public class RecordBase<T> where T : RecordBase<T>
In this way, the constraint T must beRecordBase<T>
The Update method is changed:
return conn.Update<T>((T)this);
You can compile it smoothly.
Although it can be compiled, but here is to convert the parent class into a subclass, how can it be compiled smoothly? In fact, I still have to understand the details.
I hope you can tell me.
Thank you.