关于Model数据实体层,欢迎大家来讨论。
请问大家是如何处理以下问题:
Model是数据库表的实体映射,当系统的需求出现新的变换,例如增加新的功能时数据库需要增加新的字段,
或需要去掉和更换某些旧的功能,那么对应的数据库字段肯定是会修改的。如果数据库的表结构有变换,
对应实体Model层肯定有变换。
改一个字段,
Model层必须要修改,
那么DAL层必须要修改,
SQL语句必须要修改,
表示层的数据展现也是依赖Model层的属性名称,也要修改。
这不符合设计模式的单一职责。牵一发动全身。
并且这样设计,那用啥设计模式都是白搭。
其次工作量非常大,例如商品表的话 光执行查询的地方就不得了。
请问大家是如何处理这种问题,或者怎么把影响降到最低。
[最优解释]
我也有这样的困惑,关注
[其他解释]
其实只需要model变就可以了,其他都可以不用变的,
如增加model的语句,可以根据model的属性来动态生成一个sql语句
public string GetInsertQuery(string prikey, string tableName)
{
List<string> fields = new List<string>();
foreach (PropertyInfo pi in this.GetType().GetProperties())
{
fields.Add(pi.Name);
}
StringBuilder query = new StringBuilder("insert into " + tableName + "(");
StringBuilder value = new StringBuilder(" values(");
int index = 0;
int count = fields.Count;
foreach (string key in fields)
{
query.Append(key);
value.Append(prikey + key);
if (index < count - 1)
{
query.Append(",");
value.Append(",");
}
++index;
}
query.Append(")");
value.Append(")");
return query.ToString() + value.ToString();
}
[其他解释]
可使用LINQ
http://topic.csdn.net/u/20090926/11/af162995-f4f8-4660-bed7-3949f047bde3.htmlhttp://topic.csdn.net/u/20100207/09/237128f5-a14a-44e6-a2b3-6920bc6e9538.html
[其他解释]
楼上的方法貌似 根据实体的属性名称来生成各种需要执行的SQL语句?
这也只能减少改动DAO的SQL语句 如果增加了字段。
SqlParameter还是会改变 或者是用存储过程的呢。
有没有符合设计模式原则的解决方法呢?
[其他解释]
更正一下,其实要表达的意思就是 能否对Model层进行抽象 封装变化点。
但Model层可能会随每次需求变更而更改。目的就是想只需变更Model的情况下,不影响引用它的地方。
[其他解释]
没人回答吗?自己顶起来
[其他解释]
请楼主一定坚持下去,楼主提到的问题很好,一个本该在学校就解决的问题,却没有人回答,
楼主如果是负责设计架构的,你可以换一种思维模式,你先把整个架构画出个草图,看着架构问问自己:
1、你的整个构架里为什么会有Model?
设计Model的动机?难道就是因为书上说要搞Model?
如果设计这个名叫"Model"的东西是为了所谓的映射数据库、类型化数据集,我认为是与OOD背道而驰的,
数据本来就是弱类型的、不稳定的,却偏有那么一号人要把这些在项目中描述并且还要“持久化”
2、现有架构里的Model干了什么,达到设计要求了吗?
从设计角度看:到底是先有的Model还是先有的数据库?
老师是怎么教UML的?模型驱动,整个开发所有事务都是由模型驱动的,哪个人说是数据库驱动的!
[其他解释]
接7楼:
3、我认为Model不是“实体”,是“模型”,也就是Model的职责是描述整个项目,定义everything,根据OOD的设计原则,Model应该设计成数据无关的,Model的实例可以存放在任何一种形式的DB里,比如XML、Sqlserver、Access、Excel等等,
4、如果需要修改或添加一个字段,那么要做的实际上是对Model的一个实例或者说副本进行修改(请记住刚才说了:不在代码里,在db里),根本不需要修改model的代码,更谈不上修改BLL和UI了;
5、任何一种类似于petshop的架构和类似于codesmith的代码生成器都不是终极生产模式,这些东西只能作为一种过渡的手段使用,那和复制粘贴代码没什么区别,当然我不是说复制粘贴代码不好,恰恰相反,在迈向技术成熟的历程中,我认为复制粘贴越多越好,但是复制粘贴并不是终极目标,只是重构的第一步:让更多的代码无差别;
6、在一个成熟的生产线上,其实是不需要Coder的,极少量的Code由Designer代理了,请注意:不是Coder代理Designer。
[其他解释]
model是整个架构的核心
我就是一菜鸟,个人观点仅供参考,抛砖引玉,那位大侠如果有不同意见请明示
[其他解释]
说了这么多,还没一个人说出实际解决办法,如何降低Model修改对其他层的影响呢?等待CSDN高手解答,自己顶起。
[其他解释]
7楼说的很好。我会坚持下去。
这个问题的确是在学校就该解决了,老师只告诉我们要这样做,这样做是对的,但是为什么呢?有的只说一些大道理 空话来忽悠我们。我们要的是实际
但据我发现 不管是老师讲课或者网上的设计模式都没有讲到过这个问题,
或是在回避这个问题。
看到的所有关于设计模式的文章 博客 书。都是针对某个功能,某个需求来设计。
都没有把数据和属性的加到例子中来。
[其他解释]
其实这种问题很深的,不是一两句话就可以讲清楚的,慢慢积累!
[其他解释]
[其他解释]
需求变更 总要把数据存入数据库呀,
改模型不一样会对引用它的层造成影响吗?
[其他解释]
还要说多少遍呢?
需求变更后修改的是模型,不是数据库!
[其他解释]
无论前期需求调研多么详细,最终该变的还是会变,为什么要用三层开发?其实是将原本结构化的数据库装饰成面向对象。
数据库表结构变化了,那么毫无疑问,程序员从表结构改起,实体,数据访问层,直到改界面代码,项目经理也跟着改文档,这一过程相当之烦,我针对这样的问题说说我的解决办法:
方案一:为自己的项目写代码生成器,至少可以根据表生成实体和数据访问层,这样在表结构发生改变的时候你重新生成出MODEL和DAL,覆盖老版本,OK,这样做实际上和手工改没有什么区别,不过是由程序去完成。
方案二:利用反射,也就是所谓的ORM,根据已保存的表结构配置文件或实体对象,通过反射生成出各种不同业务的SQL语句,以至于你提供一个实体,就能新增,删除,修改等等操作。请看下面一个实体,你也许会明白:
[tableInfo(tableName="sys_user",primarykey="id",foregintbl="base_employee")]
public class sys_userInfo
{
[columnInfo(columnName="ID",allownull="false",defaultname="编号")]
public int id{get;set;}
[columnInfo(columnName="LoginName",allownull="false",defaultname="登入名"]
public string loginName{get;set;}
[columnInfo(columnName="passwordd",allownull="false",defaultname="密码"]
public string password{get;set;}
//……
}
因为调用点少 与其多层 还不如一个一个改呢...
但是如果系统的业务逻辑很复杂 还是强迫自己使用这些东西吧 这些都是前辈的血泪教训
model你就不能让它跟数据库联系到一起 model有什么属性?有啥功能?是你系统设计时就定好的。
而数据库 只是你存储你的model的地方
[其他解释]
我对分层的理解:
1、分层提高程序的移植性,可以在c/s和b/s之间转换,换下表现形式即可
2、分层提高程序的灵活性,当应用逻辑发生变化的时候,重写逻辑即可
3、分层使得开发分工明确,数据库定好了,做数据开发的做数据开发,做逻辑的做逻辑,做UI的UI互不干扰。只是个时间顺序问题。
...
好多,大家可以补充补充
[其他解释]
个人认为,上面提到的特性方法解决该问题,界面是不是最终还是得程序员改呢?我曾经的一个项目中为了解决这个问题,花了很多时间在程序中提供了表单设计器的功能,考虑到复杂度,并没实现关联的查询之类,仅仅解决了单独的实体增减字段的需求,总结是,花了大量的时间仅仅提供了一个不常用的功能,回头想想,对与其增减字段还不如在每个地方手动的改代码呢!
[其他解释]
可以做个取舍……
[其他解释]
没有讨论出结果来啊
[其他解释]
如果你数据表发生变化,那么数据随之改变是不可改变的现实,但又不可说设计模式再也没作用。
因为你使用了适当的分层开发,那么受影响的应该只有是数据层,你只需要改变一下Model和DAL,而对应该的DLL应该受影响很少,这正正是分层带来的好处。
如果你没有正确使用正确设计模式,可能影响会更大。
我也遇到到相同的问题,客户的要求常常改变,所以有时候会数据库有影响,后来我用了另一种方式解决,就是通过一个从属关系建立一个附属表格,里面记录需要新建的列,从而使对DAL影响降到最低。
当然这不可能完全解决问题,但也不失为一个可行的方法。
[其他解释]
用Linq to SQL,数据表改了,删掉,再拖一个过来,就OK了,不费脑子不费事
数据的保存,更改,全对象化,Easy
多表联合查询,匿名类,随意定制,要多方便有多方便。
有人说Linq to SQL 已死,有人说Linq to SQL会有性能问题,不要相信他们说的,你自己试下,生成的SQL语句比很多人写的效率还要高。
如果非要说性能,就是解析表达示树时的性能。一般项目根本不成问题。
[其他解释]
学习学习.... 我觉得不管三层还是其他的 .只要能让程序性能变好,方便,不繁琐..该用什么就用什么
[其他解释]
抛弃Data centric first, 改换Domain-Driven first,就可以极大的消除你的问题。首先,建议停止使用ADO.NET,而选用合适的ORM Tools,比方说 NHibernate 或者Entity Framework。这样一来,你面对的是Domain Entities/Objects,也就是说,先有Domain Model, 后产生数据库。你甚至可以不必太关心Database, 也不用写任何Stored Procudure, 因为NHibernate 或者Entity Framework 会为你做任何事情。比方说,数据库可以自动生成,LINQ可以取代Stored Procudure等。当需求发生变化时,你首先要修改的是Domain Model,而不是Database。#14楼说的很明白了,现代软件设计与开发,DBA远不如以前重要了。
[其他解释]