使用ORM框架,必须迁就数据库的设计吗?

简介:

我在CSDN发表了一个帖子,发布一款强大的ORM工具--PDF.NET集成开发工具 ,有个朋友caozhy提出了非常尖锐的问题,我对他的问题做了回答,现在觉得他的问题很有深度和代表性,现在整理在这里供大家讨论。

================caozhy的问题是========================:

从技术的角度看,lz的想法是好的。

但是从商业的角度看,存在一些问题:

(1)开发者能不能得到技术支持的保证?培训谁来做?
(2)后继的维护谁来做?BUG修复?
(3)ORM的框架众多,lz的产品优势在哪里?定位简单还是功能强大?如果是简单,lz的这套语法/函数还是略显复杂。
(4)对于一款面向.NET的ORM框架,如果不兼容 IQueryable 接口是一种相当大的遗憾。这意味着,我还必须使用面向数据库架构的语法来操纵业务逻辑。
(5)支持很多数据库固然很好,但是lz如何处理数据库方言问题?对于大部分低端用户来说,能很好很简便地处理好MSSQL就很不错了。对高端用户来说,支持多数据库并不是唯一的需要,他们需要稳定、高效以及高伸缩性和可扩展性。说到底,还是定位问题。目前的Entity框架就做轻量,它无论是和IDE的整合,还是ORM以及和语言的整合,做的都很好。比如ModelFirst、CodeFirst或者根据表建模,而lz的方案看上去需要在数据库和模型代码之间定义两次,而且没有很好将数据库架构和模型分离。
(6)ORM本身的复杂性没有用过的人很难想象。lz因为既是使用者,又是开发者,所以有思维定势——如果我100%是这个框架的编写者,或者我对框架的所有实现完全掌握,我甚至会考虑使用自己的框架代替通用的ORM。但是,如果我不是框架的设计者,没有阅读过全部源代码(即使你提供代码,我有没有力量去读还是个问题),那么你假想的“轻量”、“简单”都是不存在的。简单的东西不是绝对意义上的简单,而是可以充分借鉴现有的知识以及对它的反馈有充分的把握。
(7)有没有能够说服我使用它可能并不是一个简单的例子,查询几条记录,事实上对比所有同类产品,实现这样的功能都很容易。我说几条EF的问题,不知道你的产品能否解决:
 - 对于泛型实体的支持,假设我要设计一个考试系统:

C# code
 
  
class Questions<T> where T : QuestionBase { } { public List<T> Questions { get; set; } } class QuestionBase { } class SingleSelectionQuestin : QuestionBase { public string Description { get; set; } public List< string> Options { get; set; } public string Selected { get; set; } } class MultiSelectionQuestin : QuestionBase { public string Description { get; set; } public List< string> Options { get; set; } public List< string> Selected { get; set; } } class BriefAnswerQuestin : QuestionBase { public string Description { get; set; } public string Answer { get; set; } }


这种情况下,使用目前版本的Entity框架,我必须迁就数据库的设计,这就是目前ORM缺陷的原因。
- 对于多实例可扩展性的支持
比如我的数据库部署到 SQL Server Azure 上,我的程序托管在Windows Azure WebRole里面。可能我有10个WebRole,并发访问数据库,数据一致性怎么保证?
- 非常复杂的数据库关系和架构,比如多个外键,级联查询,唯一性约束,参照完整性约束。比如自定义函数和SQL类型等等
- 数据迁移问题,说实话,数据迁移是几乎所有人都关注的核心问题,而且是衡量ORM好坏的首要标准。对于一个渐进添加功能的Web程序,程序的升级,同时保证原有的数据平滑地迁移到新的数据库里面是非常重要的事情。对于Rails的ActiveRecord,就做的很好。迁移几乎自动进行,甚至还可以反向的迁移。
在闭源产品(我是说.NET)上开发,这条路很艰辛,很多很大的产品相继倒下了,lz要慎重。

 

===============我的回答==========================:

非常感谢 caozhy 的建议和问题,下面逐一回答如下:
(1)开发者能不能得到技术支持的保证?培训谁来做?
--对于正式用户(也就是花10块钱购买源码的用户)提供在线支持,培训资料在社区有相关的博客、论坛文章;
(2)后继的维护谁来做?BUG修复?
--由于PDF.NET框架是在实际商业产品中的应用,所以维护一直在进行,功能扩展和Bug修复一直在进行中;
(3)ORM的框架众多,lz的产品优势在哪里?定位简单还是功能强大?如果是简单,lz的这套语法/函数还是略显复杂。
--框架的主要特点是具有iBatis的SQL-MAP功能和支持.NET 2.0的面向对象方式的查询表达式OQL,定位是简单易用,在使用
SQL-MAP的时候,只需要写好SQL语句,有代码工具自动生成DAL代码;在使用OQL的时候,大部分都是单表简单的CRUD操作(
复杂的SQL语句都用SQL-MAP实现了),OQL.From(entity).Select(entity.Property,...).Where(entity.Property) 这样的语法还是很简单的,
很类似SQL的写法,如果有比较复杂的条件,可能表达式构造稍显得复杂(但复杂的SQL都用SQL-MAP去实现了),Update、Insert、Delete操作
最简单,不用多说了;
(4)对于一款面向.NET的ORM框架,如果不兼容 IQueryable 接口是一种相当大的遗憾。这意味着,我还必须使用面向数据库架构的语法来操纵业务逻辑。
--由于历史原因,框架最初定位在支持.NET2.0,IQueryable 是.NET 3.0以后才支持,目前正在考虑框架直接支持LINQ;
(5)支持很多数据库固然很好,但是lz如何处理数据库方言问题?对于大部分低端用户来说,能很好很简便地处理好MSSQL就很不错了。
--正因为有不同数据库的方言问题,所以框架使用SQL-MAP技术,将那些需要高效执行的、数据库特性的SQL单独写到配置文件中,当需要切换数据库的时候,
仅仅替换这个SQL配置文件即可(SQL-MAP配置文件);
“比如ModelFirst、CodeFirst或者根据表建模...”
--框架提供了从数据库来生成实体类的工具,但也允许你先ModelFirst、CodeFirst,我的许多示例(比如示例操作OQL的部分)都是直接创建实体类,
没有设计数据表的,如果采用手工方式,你可以自定义要持久化哪些属性以及如何持久化;
(6)ORM本身的复杂性没有用过的人很难想象...但是,如果我不是框架的设计者...那么你假想的“轻量”、“简单”都是不存在的。
不太认同你说的“不是设计者”就无法肯定框架是“轻量、简单”的这个观点,“轻量”可以从软件的文件大小、对环境、系统的依赖程度等方面来认定;
“简单”可以从实际使用过程体会出来,已经有不少用过或者看过框架的朋友肯定的说“确实简单”了,例如参看这篇文章的回复:
http://www.cnblogs.com/bluedoctor/archive/2011/04/01/2001887.html


不使用反射的实体类方案
http://www.cnblogs.com/bluedoctor/archive/2010/02/08/1665795.html


7)有没有能够说服我使用它可能并不是一个简单的例子...
--首先,框架不是个人闭门造车的产物,而是实实在在的项目应用的结果,比如最近我们做的银行基金分析系统,这样的系统复杂性和数据量自然不用怀疑的;
对于你的“对于泛型实体的支持”的问题,我想不是在泛型类本身支持实体的问题,而是QuestionBase具体实现类如何支持实体类的问题,你可以先CodeFirst,
先设计“领域模型”(我认为你给的例子不再是一个简单的实体类了,而是一个领域模型),再手工对实体类进行持久化,例如持久化SingleSelectionQuestin:

首先,建议你将 QuestionBase 定义为接口,

C# code
 
  
interface QuestionBase { public ID{ get; set;} }


然后,修改单选实体类:

C# code
 
  
class SingleSelectionQuestin : QuestionBase,EntityBase { public string Description { get{ return getProperty< string>( " Description ");} set{getProperty< string>( " Description ",value, 50);} // 假设Description 字段长度为50 } public string Tb_Options { get{ return getProperty< string>( " OptionList ");} private set{getProperty< string>( " OptionList ",value, 500);} // 假设OptionList 字段长度为500 } public List< string> Options { // 假设Options 的结果以逗号分隔的字符串的形式,存在与数据库表字段OptionList 中 get{ this.Tb_Options.split( ' , ').ToList();} set{ this.Tb_Options= string.join(value.ToArray(), " , ");} } public string Selected { get{ return getProperty< string>( " Selected ");} set{getProperty< string>( " Selected ",value, 50);} // 假设Selected 字段长度为50 } public int ID { get{ return getProperty< int>( " ID ");} set{getProperty< int>( " ID ",value);} } public SingleSelectionQuestin() { TableName = " TB_SingleSelectionQuestin "; // 表名称 // IdentityName = "标识字段名"; IdentityName= " ID "; // PrimaryKeys.Add("主键字段名"); PrimaryKeys.Add( " ID "); } protected override void SetFieldNames() { PropertyNames = new string[] { " ID ", " Description ", " Selected ", " OptionList "}; } }


最后,在你需要的地方来获取QuestionBase类的实例,例如:

C# code
 
  
QuestionBase question= QuestionFactory.GetQuestionInstance(); // 假设有这一个问题类工厂 question.ID= 100; // 给问题ID赋值 EntityBase entity=question as EntityBase; // 实体类基类 EntityQuery<EntityBase>.Fill(entity); // 填充该实体 // 下面对实体类进行其它操作 EntityQuery<EntityBase>.Instance.Update(entity); // 保存修改


这段代码可以放到你需要的地方;

使用这种CodeFirst的方式,最后根据需要来持久化实体类,就不需要迁就数据库表的设计了。

(8)- 对于多实例可扩展性的支持
--并发访问数据库,数据一致性的要求,对于ORM来说是不是要求太高了些?这些应该是数据库或者专门的业务层去做的事情;
(9)- 非常复杂的数据库关系和架构,比如多个外键,级联查询,唯一性约束,参照完整性约束。比如自定义函数和SQL类型等等
--PDF.NET的实体类本着从简的原则,实体类没有引入复杂关系的概念,遇到这些复杂的查询,可以使用SQL-MAP功能,它可以将DataReader的结果读入实体类中;
(10)- 数据迁移问题,说实话,数据迁移是几乎所有人都关注的核心问题,而且是衡量ORM好坏的首要标准。
--下面这个场景是否与你的这个问题类似?
我们有一个系统,有一部分基础数据需要从我们的SQLSERVER库远程同步到客户的系统中,而客户的系统采用的数据库目前有SQLSERVER,PostgreSQL,这样的数据同步
算不算类似你说的数据迁移呢?请参见我下面的文章:
唯一不变的就是一直在变”--“数据”的华丽“变身术”  
http://www.cnblogs.com/bluedoctor/archive/2011/02/23/1962218.html


在系统的实现中,有关数据的导入和导出,采用实体类很好的屏蔽了数据的差异,比如目标表和源表字段名称和数量不一致的问题。

注:有关PDF.NET数据访问框架的问题,请参看官网地址

http://www.pwmis.com/sqlmap

或者我的博客相关文章。



    本文转自深蓝医生博客园博客,原文链接:http://www.cnblogs.com/bluedoctor/archive/2011/05/03/2035107.html,如需转载请自行联系原作者



相关文章
|
4月前
|
关系型数据库 MySQL 数据库
ORM对mysql数据库中数据进行操作报错解决
ORM对mysql数据库中数据进行操作报错解决
108 2
|
1月前
|
SQL 定位技术 数据库
深入探索Django ORM:高效数据库操作的秘诀####
本文旨在为读者揭开Django ORM(对象关系映射)的神秘面纱,通过一系列生动的比喻和详实的案例,深入浅出地讲解其核心概念、工作原理及高级特性。我们将一起探讨如何利用Django ORM简化数据库交互,提升开发效率,同时确保数据的一致性和安全性。不同于传统的技术文档,本文将以故事化的形式,带领读者在轻松愉快的氛围中掌握Django ORM的精髓。 ####
|
4月前
|
存储 关系型数据库 MySQL
【阿里规约】阿里开发手册解读——数据库和ORM篇
从命名规范、建表规范、查询规范、索引规范、操作规范等角度出发,详细阐述MySQL数据库使用过程中所需要遵循的各种规范。
|
3月前
|
SQL Go 数据库
【速存】深入理解Django ORM:编写高效的数据库查询
【速存】深入理解Django ORM:编写高效的数据库查询
109 0
|
5月前
|
Java 数据库连接 数据库
告别繁琐 SQL!Hibernate 入门指南带你轻松玩转 ORM,解锁高效数据库操作新姿势
【8月更文挑战第31天】Hibernate 是一款流行的 Java 持久层框架,简化了对象关系映射(ORM)过程,使开发者能以面向对象的方式进行数据持久化操作而无需直接编写 SQL 语句。本文提供 Hibernate 入门指南,介绍核心概念及示例代码,涵盖依赖引入、配置文件设置、实体类定义、工具类构建及基本 CRUD 操作。通过学习,你将掌握使用 Hibernate 简化数据持久化的技巧,为实际项目应用打下基础。
440 0
|
5月前
|
数据库 Java 数据库连接
玩转Play Framework的秘密武器:Ebean ORM带你解锁高效数据库操作新姿势,让你的代码从此飞起来!
【8月更文挑战第31天】Play Framework 以其简洁的 API 和高效开发体验著称,Ebean ORM 则是其推荐的对象关系映射(ORM)工具之一。Ebean 可将 Java 对象轻松映射到数据库表,简化数据库交互。本文将指导你在 Play Framework 中使用 Ebean ORM 进行数据库操作,涵盖项目创建、依赖引入、数据库配置、模型定义及 CRUD 操作,并通过示例代码展示实现过程。通过这些步骤,你将学会如何利用 Ebean 的丰富功能,如事务管理、查询构建等,提升 Web 应用的数据库交互能力。
87 0
|
5月前
|
数据库 测试技术 开发者
Play Framework的测试魔法:让代码在舞台上翩翩起舞,确保应用质量的幕后英雄!
【8月更文挑战第31天】Play Framework不仅以其高效开发与部署流程著称,还内置了强大的测试工具,提供全面的测试支持,确保应用高质量和稳定性。本文将详细介绍如何在Play Framework中进行单元测试和集成测试,涵盖`WithApplication`、`WithServer`及`WithDatabase`等类的使用方法,并通过示例代码手把手教你如何利用Play的测试框架。无论是单元测试、集成测试还是数据库操作测试,Play Framework均能轻松应对,助你提升应用质量和开发效率。
60 0
|
5月前
|
SQL 关系型数据库 数据库连接
Entity Framework Core 入门教程来袭!快速上手强大的 ORM 工具,开启高效数据库开发之旅!
【8月更文挑战第31天】Entity Framework Core(EF Core)是一个轻量且可扩展的对象关系映射(ORM)框架,允许开发者使用 .NET 语言操作数据库而无需直接编写 SQL 语句。本教程涵盖 EF Core 的安装、数据库上下文创建、数据库连接配置及常见数据库操作(如添加、查询、更新和删除),并介绍如何利用数据库迁移功能安全地更改数据库结构。通过本教程,你可以快速掌握 EF Core 的基本用法,提高开发效率。
337 0
|
5月前
|
API 数据库 开发者
【独家揭秘】Django ORM高手秘籍:如何玩转数据模型与数据库交互的艺术?
【8月更文挑战第31天】本文通过具体示例详细介绍了Django ORM的使用方法,包括数据模型设计与数据库操作的最佳实践。从创建应用和定义模型开始,逐步演示了查询、创建、更新和删除数据的全过程,并展示了关联查询与过滤的技巧,帮助开发者更高效地利用Django ORM构建和维护Web应用。通过这些基础概念和实践技巧,读者可以更好地掌握Django ORM,提升开发效率。
59 0

热门文章

最新文章