多层结构应用各层之间数据传递的问题

gqming 2007-11-28 02:30:00
目前在实验一个3层架构的应用,具体分层如下
1 表示层
2 业务逻辑层
3 数据访问层

对于每个具体的业务模型对象(实体)数据库中会存在一个相应的表,表有多少个字段,那么实体类就有多少个属性
一般情况下,关系数据库中表与表之间都是一定的关联关系的,举个例子,论坛用户和帖子,分别用User,和Post来表示,具体数据库表和实体类结构如下:

User
---------------------------
UserId 唯一标识
LoginId 登录ID
Passwd 密码
NickName 昵称
.....

Post
--------------------------
PostId 唯一标识
Title 标题
CreatedOn 创建日期
CreatedBy 创建者标识(与User的UserId关联)
.....


针多上面的结构,需要查询出某个时间段内所有帖子,并已列表的形式显示.
并且需要在列表中包含用户的昵称(NickName)列,这个很常见的应用。
SQL:
SELECT p.*,u.NickName FROM Post AS p
LEFT JOIN User AS u ON u.UserId=p.CreatedBy
WHERE p.CreatedOn>=@StartDate AND p.CreatedOn<=@EndDate
ORDER BY p.CreatedOn DESC

通过这个SQL查询得到的是一个记录集,而且里面多出了一个NickName属性,而我们的Post实体类中并不包含
NickName这个属性,因为本来也不是应该属于他的属性。这时候我们就没法构建IList<Post>类型的数据集合了。
针对这个问题,我一直没找到好的解决方法。期待高手解惑。。。

目前,因为上面的原因,各层间数据传递的媒介我是采用 实体类,IList<实体类>, DataSet, DataTable结合的方式。

1. 简单获取某个实体对象用实体类
2. 获取记录集合时能够造出实体对象时使用IList<实体类>
3. 获取记录集合时不能够造出实体对象(多个表)时使用DataSet
4. 获取记录集合时不能够造出实体对象(单个表)时使用DataTable


如果都能够传递实体或者实体集合的话就是理想的情况了,这样在表示层就不需知到数据库有什么字段或者说一个查询返回的字段列表了,因为实体是强类型的,表示层需要什么就去访问相关的属性就行了。

如果传回来的是DataSet/DataTable,那么必然要知道数据库中的字段名才能正确地在表示层表示出来。
...全文
662 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
Kshatriya 2008-01-14
  • 打赏
  • 举报
回复
能降低耦合,适应变化就是好的分层
pone 2008-01-03
  • 打赏
  • 举报
回复
同问
秋儿-Angel 2008-01-02
  • 打赏
  • 举报
回复
对要 如果采用分层,是会出现这些问题,用什么解决方案好呢? 我也在寻求,不知道那位有好的方案.
Erice 2007-12-28
  • 打赏
  • 举报
回复
MVC 的View 不仅仅代表了页面,同时也指出了View 可能是Model之间通过关联的视图。(当然,关联也代表了一种业务逻辑)。那么这个时候,你只有建立ViewModel,去展示给用户。。。

Hibernate中对于这种动态model的处理是通过Hashtable来处理的。

我目前就想写这种情况的ORM的组件。

以前的项目中,我是通过视图来完成,Ui 和BusinessLayer 之间传递的是数据集对象,然后通过DataAccessLayer 自动处理View Transfer Table 的过程!

所以,用Model参与开发时,首先要考虑展示和提交之间的问题。

以上纯属个人意见。不要拍砖哈
possible_Y 2007-12-17
  • 打赏
  • 举报
回复
CreatedBy 设计成User类型的,而不是只是一个int的UserID

这个地方才是Relation的体现
xiaojing7 2007-12-14
  • 打赏
  • 举报
回复
难度问题,学习`
zuu_zuki 2007-12-12
  • 打赏
  • 举报
回复
有深度,学习中...
sunnf 2007-12-06
  • 打赏
  • 举报
回复
学习
Software 2007-12-03
  • 打赏
  • 举报
回复
mark
ahshow 2007-12-03
  • 打赏
  • 举报
回复
适合的就行了,没必要太拘泥形式和分层
绝代坏坏 2007-12-02
  • 打赏
  • 举报
回复
Castle+IBatisNet
bwangel 2007-12-02
  • 打赏
  • 举报
回复
那种一个表对应一个类的方法完全是狗P,现实中哪有这么理想的情况。
曲滨_銘龘鶽 2007-12-02
  • 打赏
  • 举报
回复
如果一定要实体的话继新加一个类承 Post 在加一个属性
要么用DataTable;

要么等VS2008 linq 里有个动态实体类;
heguo 2007-12-02
  • 打赏
  • 举报
回复
所以说,ORM不是万能的,这种"复杂"查询用ORM总是很难实现,即便实现了不在性能上打折扣,也在代码美观程度上打了折扣.
我通常的做法是另定义一个UserPost类,专用来返回查询结果.
不知道在Linq中,这种情形会不会有好的解决方案.
gqming 2007-11-28
  • 打赏
  • 举报
回复
从数据层返回到业务逻辑层的是一个记录集包含了Post表的全部字段和一个额外的Nickname字段
按照楼上做法,需要在逻辑层进行循环遍历对每一条记录构建一个Post实例并把对每个post实例够一个Creator实例然后设置Post.Creator.Nickname的属性,填充一个IList<Post>集合返回给表示层进行显示处理,大致伪代码如下

public IList<Post> GetPosts(DateTime startDate,DateTime endDate)
{
DataTable dt=Get Data From DataAccessLayer

Post post=null;
IList<Post> postList=new List<Post>();
foreach(DataRow dr in dt.Rows)
{
post=new Post();
post.PostId=(int)dr["PostId"];
post.Title=(string)dr["Title"];
....

//构建post的creator实例
post.Creator=new User();
post.Creator.NickName=(string)dr["NickName"];

postList.Add(post);
}

return postList;
}

这里在业务逻辑层中已经对记录集进行一次循环,在显示层中势必还会进行一次循环,不管用什么方式DataBind还是自己手动输出。这样性能方面就要打折扣了。

其实我说的这个例子只是很简单的一个应用。假如上面还要进行一点扩展,而外还要返回用户的这段时间的发帖数量(或者其他的一种动态的统计量,好像不能加到User的属性中去吧,因为是时间段查询的)呢,又该如何实现。
vrhero 2007-11-28
  • 打赏
  • 举报
回复
如果传回来的是DataSet/DataTable,那么必然要知道数据库中的字段名才能正确地在表示层表示出来。
-----------------------
你的业务逻辑层干什么用?


例...业务逻辑层对象...

Post.Creator //属性...

User Creator //User类型...更好的做法是抽象出IUser接口...

显然你并没有真正理解OO及分层...

13,190

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 分析与设计
社区管理员
  • 分析与设计社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧