C#之ORMapping对象关系

C#之ORMapping对象关系

2023年7月20日发(作者:)

C#之ORMapping对象关系

在我们的系统中,存在⼤量的需要进⾏持久化存储的对象,这些对象可能是各种各样的业务单据,也可能是我们的系统配置信息等。另外⼀些属于内存中使⽤⽽不需要进⾏持久化存储的对象,不属于我们的讨论范围。⽽在⽀持对象序列化的语⾔⽐如C#,Java中,我们可以将这些对象序列化到磁盘⽂件或者直接保存到关系数据库中。其中关系数据库是我们最主要也是最安全的选择。在对数据库中的业务数据进⾏各种操作的时候我们发现,我们进⾏的⼤量的Insert、Update、Delete操作,除了其SQL语句根据不同的对象有不同的变换之外,其主要流程存在很多相似之处。于是⼈们就想通过⼀个东西来实现这些相同部分的操作的⾃动化,⽽那些不同的流程,操作再做特殊处理。这样我们就可以把主要的精⼒都集中在那些个性化的,特殊的流程操作上。这就是ORM产⽣的根本原因。在Java的世界⾥,ORM框架的应⽤⽐较早,也⽐较成熟,⽐如Hibernate等,⽽在.NET世界⾥,起步就相对晚的多。但是由于担⼼使⽤开源的ORM框架导致项⽬更为复杂(因为这些开源⼯具虽然很好,但是各个项⽬总是存在⾃⼰特殊的地⽅。所以⽬前不敢⽤)。但是我们确可以⾃⼰设计开发些⼩型的,尽量符合⾃⼰项⽬的ORM。可是不论怎么样,我们都需要对ORM有⼀定的了解:⼀、对象的继承结构:在⽀持OO的语⾔中,继承是最重要的概念之⼀,所以我们的ORM也应该对继承作出相应的⽀持。⼀般来说,对于ORM世界中的继承有三种模式:1、⼀个继承树映射到⼀个表(ONE_INHERITANCE_TREE_ONE_TABLE):即将具有相同⽗类的所有类都映射到⼀个表中,这些类属性映射的并集组成了这个表的所有列,在这种情况下,只需要对最底层的类进⾏映射。如下⾯⼀个类结构:在上⾯的类结构中,⽗类有属性Property1和Property2,⽽⼦类Child1有属性Property3,⼦类Child2有属性Property4。所以如果采⽤ONE_INHERITANCE_TREE_ONE_TABLE映射模式的话,数据库中只有⼀张表。类属性Property1Property2Property3Property4数据库表字段Field1Field2Field3Field4但是这种模式存在⼤量的属于冗余,对于Child1,由于没有Property4属性,所以字段Field4是冗余字段。同样,对于Child2,Field3是冗余字段。但是这种模式的优点的简单。2、⼀个继承路径映射到⼀个表(ONE_INHERITANCE_PATH_ONE_TABLE):同样⼀上⾯的类结构,数据库中将存在两张表,分别对应于Child1和1对应的数据库表:类属性Property1Property2Property3Child2对应的数据库表类属性Property1Property2Property4数据库表字段Field1Field2Field4数据库表字段Field1Field2Field3这种模式的优点是没有数据冗余,但是缺点也是很明显的,那就是,当我们想根据Parent来查找满⾜Parent的Child1和Child2的时候,就必须同时对两张数据库表进⾏查找,当继承数横向很⼤的时候,这种查找将导致⼤量的性能下降。3、⼀个类映射到⼀个表(ONE_CLASS_ONE_TABLE):对于上⾯的类结构,对于的数据库表如下。这种模式下,每个类对应于⼀个数据库表,其中字表和⽗表通过ID进⾏关联。当然这种⽅式的优点是数据冗余⼩,但是缺点是,当继承关系很复杂的时候,我们构造SQL也会变得相当复杂,从⽽导致修改变的也很复杂。效率也会降低。当然了,如果⼀个类没有⽗类也没有⼦类哪么上⾯三种模式都是⼀样。⼆、对象的组合结构:对象的组合结构是指⼀个对象中包含若⼲不同类型的⼦对象,⽐如⼈(Person)对象包含了⼿(Hand)对象,头(Head)对象等。这些都是ORM应该考虑的问题。三、对象状态:对象⼀般包括如下⼏个状态:1、还没有和任何数据库数据关联的对象,⽐如刚new出来的对象,此时对象中没有任何实际数据。2、对象初始化并且设置了属性值,但是还没有被保存,此时需要使⽤ORM的Insert功能。3、从数据库中读取出来的数据对象,并且已经修改,此时对象对应于数据库中某条记录。4、数据库中记录已经被删除了的对象。上⾯⼏种状态需要在我们的ORM中能有所体现。⽐如对于第⼀种状态,我们需要对其设置属性值,然后转换成第⼆种状态。在ORM中执⾏Insert操作。对于第三中状态,我们需要执⾏Update操作,第四种状态我们应该进⾏错误提⽰。四、ORM中的事物处理:事物处理是每个底层框架都应该考虑的问题,即使不能提供⾃有的事物处理模型,⾄少也要能够提供能够进⾏事物处理的接⼝等。.NET中事物处理有两种⽅式,⼀种是使⽤COM+,通过使⽤TransactionScop来实现事物处理,这种⽅式性能有⼀定的下降,但是整个代码显得⾮常优美。另外⼀种⽅式是通过SqlTransaction来实现事物处理。由于我曾经被COM+弄的很惨,所以我这⾥推荐使⽤SqlTransaction。五、O/R Mapping的⼀般做法:要实现对象和关系之间的映射,我们需要定义映射规则,也就是类的属性和数据库表字段之间的⼀⼀对应规则。⽐如上⾯所说的ty3对应数据库表中的Field3字段。在.NET中我们可以通过⾃定义Attribute来实现。好像也能够通过配置⽂件来描述映射规则,但是我这⾥仅仅讨论的是Attribute的形式。(以上内容Copy的) 但是对于许多对象来说可能还存在着⼀下⼏个⽅⾯的问题。因为简单的表和对象之间的关系并不能很好的满⾜对象和对象关系的这种需求。⽐如说⼀个对象和另⼀个对象存在⼀⼀对应的关系。解决⽅案 :如何表达这种关系呢,⽐较简单的⼀种做法就是在对象⾥⾯再有⼀个属性。⽤这个属性来表达这种关系。对象有⼀对多的关系呢,如果再扩展⼀下,如果这个对象的本⾝是和其他的对象有⼀对多的关系呢。⽐如医⽣和病⼈(1对多少还是不能确定的)。那么怎么样来表达呢。解决⽅案 :第⼀: 当然也可以⽤属性的⽅法,这个属性的本⾝就结构话的,就是说这样⼀个属性就是⼀个其对应的对象集合。但是这种是⽤结构话的⽅法来满⾜他们这种对应关系的话还是特化了。第⼆ ⽤另外的⼀种表结构的形式来维护他们对象和对象之间的关系。第三 我们就不需要想那么多问题了,定义对象的时候我们就在这个对象⾥⾯加这样⼀个对象的集合做为属性,持久化的时候直接把这个对象的本⾝给序列化。

发布者:admin,转转请注明出处:http://www.yc00.com/news/1689825857a288978.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信