ORM的思考


ORM的思考




单刀直入

首先我很怀疑ORM中查询的复杂程度是否必要。当然LINQ是个很强大的东西,但是面对80%的简单操作,为什么不只是用20%的努力呢?

我看了NBear, toplink, hibernate,他们都在select上面下了很大的功夫,在xx to xx mapping上面提供了很多的映射模型。但是这些必要吗?


我的IDEA --- MAPPING

我的想法很简单,既然使用了ORM,用户就根本不要考虑到底对象怎么去映射到了数据库,数据库的字段怎么去读取。管他这么多。就像一个磁盘被配置成了RAID 10的时候,你会考虑某条数据放在哪里吗?

所以,即使ORM把数据库表空间管理的乱七八糟,表明字段名、表约束、外键都看不懂了,但是只要面对用户的时候,ORM能够正确的读取,那么就行了。

根据这点,我设计ORM的时候,很多mapping使用了自己规定的方式,连表名我都自己去规定了,不让用户操心。用户只要乖乖的去处理对象就好了。

我的IDEA --- SELECT

再说回查询,看见oracle的toplink里面session超级长的查询,再看看nbear,也是复杂的看不懂。

我现在在内存中处理对象的时候,一般的查询都很简单.
schema.GetTable(string tablename)
就这样,哪来什么又这个嵌套,又那个groupby。这些是关系数据库的功能,为什么要用在对象数据库?不解。

如果真的用到了复杂的查询,即使没有数据库,我也需要写代码,例如找一个数据库里面是否存在循环外键,我相信查询功能再强大也很难满足我这个需求。

所以ORM里面给用户的查询要很简单,可能根据几个 == 就能够找到了。但是面对复杂的查询操作,要么设计一套面向对象的存储过程,要么写代码逻辑。别把查询复杂化。

我的IDEA --- 模型建立

最后我帖一个我设计的ORM模型:

            ObjectProxy schema = new ObjectProxy();

            schema 
= schema.Select("TEST");

            Console.Write(schema.Get(
"TABLE").Select("ITM_ITEM").Get("COLUMN").Select("ITEMCODE").Get("COLUMNNAME").Value);


解释一下:我这个对象是数据库的元数据对象。操作结果是数据库TEST中表ITM_ITEM的字段ITEMCODE的字段名是什么,当然,返回值就是ITEMCODE

至少,如果不使用数据库,单纯的内存对象操作,代码形式都是接近的。

schema.GetTable("ITM_ITEM").GetColumn("ITEMCODE").ColumnName ( of course = ITEMCODE)

至少,使用了ORM,感觉和没用一样。

我觉得这样才算是可用的。


后记

我觉得只要相互取笑、鄙视,才能激发人的斗志,这个世界才会进步。所以请取笑我。但是也请在取笑我的同时,给我一个原因、到底、或者更好的解决方案。



问题汇总

Question 1:
schema.Get("TABLE").Select("ITM_ITEM").Get("COLUMN").Select("ITEMCODE").Get("COLUMNNAME").Value
你有没有发现很多组件的想把"ITM_ITEM"这样的String编写方式去了是出于什么原因吗?
你认为你这相比直接SQL省事方便?
不信自己可以写这样一个SQL来对比一下,当然SQL还需要加上Connection等东本(但那些都是封装上的问题)
Context.Execute("select * from customer");

Answer 1:

这个问题在我没有花几天时间去看orm的时候也怀疑着。
但是我看到了hibernate里面的理论之后,突然想开了点。感觉orm导致的是个思路的转变。

例如我们有个对象

 

class 订单 

string 订单编号 
List
<订单子表> 订单子表1 

 

class 订单子表 

string 子表编号 

在面向对象中,这种关系经常看见。但是怎么保存在数据库呢?我没有接触orm之前,使用了序列化,保存为xml了。但是之后,我有所领悟。

顺便说一下我这个模型,是个代理。objectproxy。不是最终用户使用的。但是用户自定义的类会被映射到这个模型。

思路和.net里面的消息机制一样,ImessageSink。


Question 2:

引用楼主“再看看nbear,也是复杂的看不懂。”

nbear很复杂吗?不说别的,他的强类型查询我就认为是最自然,最舒服的方式。

说句实话,你的Noebe我看过,还真的不如直接使用Sql。

Answer 2:

谢谢你看过。不过你看到了只是noebe查询部分和sql一致。非常正确,我不想用自以为是的框架去取代强大的sql。框架再强大,也不能取代sql。所以在查询部分,我暴露了sql接口。
但是我把剩下的都做的很简单,比如Insert, Update, Delete。相信这不是几个sql能够解决的。


原文地址:https://www.cnblogs.com/zc22/p/928313.html