I have been building a car behind closed doors all the time. Today I read an important ORM from Microsoft.ArticleNext-generation Data Access: Making concepts a reality, which describes in detail the ideas and implementation of next-generation data access by Microsoft. I have a section on the conceptual model.CodeHe is quite interested because he is very similar to torridity (Our ORM framework name) I designed.
- Location of the keyword description
In the keyword description of MS, an important change is that the keyword is described in the entity rather than in the field:
<! -
Typical entity definition, with the Identification [keyword] and some members
-->
<Entitytype name = "product" Key = "productid">
<Property name = "productid" type = "system. int32" nullable = "false"/>
In many ORM implementations, it is put in fields. I think that is wrong. Now let's look at our definition:
<Dataentitytype name = "team" primarykey = "teamid">
<Simpleproperties>
<Simpleproperty dbtype = "string" isunique = "false" Index = "false" name = "teamid" isbrowsable = "false"/>
<Simpleproperty dbtype = "string" isunique = "false" Index = "false" name = "code"/>
<Simpleproperty dbtype = "string" isunique = "false" Index = "false" name = "name"/>
</Simpleproperties>
</Dataentitytype>
Since it is an Orm, inheritance is of course indispensable. MS is defined using the following method:
<! -
Derived product, which can map TPH, TPC, and TPT
-->
<Entitytype name = "discontinuedproduct" basetype = "product">
<Property name = "discreason" type = "system. String"
Nullable = "false" size = "Max"/>
</Entitytype>
We use the same method:
<Dataentitytype name = "comparisonexpense" basetype = "comparisonbase">
<Simpleproperties>
<Simpleproperty dbtype = "decimal" isunique = "false" Index = "false" name = "estimateexpense"/>
<Simpleproperty dbtype = "decimal" isunique = "false" Index = "false" name = "actualexpense"/>
</Simpleproperties>
</Dataentitytype>
Composite types are extensions of simple types. They actually support object attributes. Ms is defined as follows:
<! -
Complex types only define structures rather than identifiers. Yes
Embedded in 0 or more object definitions
-->
<Complextype name = "ctaddress">
<Property name = "Address" type = "system. String"
Nullable = "false" size = "Max"/>
<Property name = "city" type = "system. String"
Nullable = "false" size = "Max"/>
<Property name = "postalcode" type = "system. String"
Nullable = "false" size = "Max"/>
<Property name = "region" type = "system. String"
Nullable = "false" size = "Max"/>
<Property name = "fax" type = "system. String"
Nullable = "false" size = "Max"/>
<Property name = "country" type = "system. String"
Nullable = "false" size = "Max"/>
<Property name = "phone" type = "system. String"
Nullable = "false" size = "Max"/>
</Complextype>
<Entitytype name = "customer" Key = "customerid">
<! -The address is a member that references embedded complex types -->
<Property name = "Address" type = "cnorthwind. ctaddress"
Nullable = "false"/>
<Property name = "companyName" type = "system. String"
Nullable = "false" size = "Max"/>
<Property name = "contactname" type = "system. String"
Nullable = "false" size = "Max"/>
<Property name = "contacttitle" type = "system. String"
Nullable = "false" size = "Max"/>
<Property name = "customerid" type = "system. String"
Nullable = "false" size = "Max"/>
</Entitytype>
The composite type is not explicitly indicated in torridity: complextype. You can use any entity as the composite structure.
<Dataentitytype name = "callresult" primarykey = "callresultid" isroot = "false">
<Simpleproperties>
<Simpleproperty dbtype = "string" isunique = "false" Index = "false" name = "callresultid"/>
<Simpleproperty dbtype = "string" isunique = "false" Index = "false" name = "resultdescription"/>
</Simpleproperties>
<Complexproperties>
<Complexproperty dataentitytype = "picklistentitycpx" name = "result"/>
<Complexproperty dataentitytype = "picklistentitycpx" name = "objectivetype"/>
<Complexproperty dataentitytype = "productcpx" name = "mainproduct"/>
</Complexproperties>
</Dataentitytype>
- Set attributes are supported.
In Ms design, set attributes are described as follows:
<! -
Between product [as defined above] and orderdetails [not displayed for concise purposes]
Example of Association
-->
<Association name = "order_detailsproducts">
<End name = "product" type = "product" multiplicity = "1"/>
<End name = "order_details" type = "orderdetail" multiplicity = "*"/>
</Association>
In torridity, one-to-one is called a reference attribute, and one-to-many is called a set attribute. It is defined in the following way:
<Dataentitytype name = "orders" basetype = "quotationbase" primarykey = "orderid">
<Simpleproperties isexpansion = "true">
<Simpleproperty dbtype = "string" isunique = "false" Index = "false" name = "orderid"/>
<Referenceproperty referenceto = "quotations" dbtype = "string" isunique = "false" Index = "false" name = "quatationid"/>
<Simpleproperty dbtype = "decimal" isunique = "false" Index = "false" name = "totalmargin"/>
</Simpleproperties>
<Collectionproperties>
<Collectionproperty itemdataentitytype = "revenueassignment" name = "revenueassignments"/>
</Collectionproperties>
<Complexproperties>
<Complexproperty dataentitytype = "picklistentitycpx" name = "sourceid"/>
</Complexproperties>
</Dataentitytype>
Note the difference between referencing attributes: Ms points to a type, and we point to an object (typekey ). I think the design of MS is defective.
The physical container is supported in ms, and the functions seem to be better:
<! -
Entity container definable
Entitysets (a set of multiple-form instances) and
Associationsets (used to associate two or more physical instance logical chain tables)
Logical Encapsulation
-->
<Entitycontainertype name = "cnorthwind">
<Property name = "Products" type = "entityset (product)"/>
<Property name = "customers" type = "entityset (customer)"/>
<Property name = "order_details" type = "entityset (orderdetail)"/>
<Property name = "orders" type = "entityset (Order)"/>
<Property name = "order_detailsorders"
Type = "relationshipset (order_detailsorders)">
<End name = "order" extent = "orders"/>
<End name = "order_details" extent = "order_details"/>
</Property>
<Property name = "order_detailsproducts"
Type = "relationshipset (order_detailsproducts)">
<End name = "product" extent = "Products"/>
<End name = "order_details" extent = "order_details"/>
</Property>
</Entitycontainertype>
In torridity, collection classes are automatically created without specific definitions.
I have a very strange question. Since ORM is object-oriented, why does it not containVery important concept: Interface. (Maybe the author forgot ).
Supported in torridity:
<Dataentitytype name = "quotations" basetype = "quotationbase" primarykey = "quotationid">
<Interfaces>
<Interface name = "icreateobject"/>
<Interface name = "iownerobject"/>
<Interface name = "inoteaccessoryobject"/>
<Interface name = "icodeobject"/>
<Interface name = "iversionobject"/>
</Interfaces>
<Simpleproperties>
<Simpleproperty dbtype = "string" isunique = "false" Index = "false" name = "quotationid"/>
<Simpleproperty dbtype = "datetime" isunique = "false" Index = "false" name = "startdate"/>
<Simpleproperty dbtype = "datetime" isunique = "false" Index = "false" name = "expiredate"/>
</Simpleproperties>
</Dataentitytype>
By supporting interfaces, the entity design is greatly simplified, andProgramDesign more regulations. We know that a real domain model cannot be described by inheritance, but can be described by features (that is, interfaces.