[已解决问题] 三层架构下的Linq的疑惑
提问时间: 2008-06-16 16:52
悬赏分:10 浏览:460 次

我个人创建的3层:DAL,BLL,WEB.        数据库(Northwind)

DAL:VS设计器直接生成linq的.dbml文件。

BLL:Insert(),Update(),Delete(int id),GetList(),GetById(int id)

WEB:页面

现在有一个疑问:要在页面显示某个商品的具体信息。调用Bll的GetById(int id)方法.

        public Product GetProductById(int productId)
        {
            Product q = (from p in db.Products
                                    where p.ProductID == productId
                                    select p).First();
            return q;
        }

返回的类型是Product类,而这个类的定义是在DAL层中的linq生成的文件里。

web层一般是返回一个实体Model类。Web调用BLL的代码是:

 var bll = new ProductBll();

Product p = bll.GetProductById(id);

string name = p.ProductName;

红色的Product是DAL声明的。

现在问题是:需要再创建一个Model项目来解决这个类的问题嘛?如果创建了。好像有点重复的。如果不创建这个类。WEB层中的Product类如何实现的。

提问者:迭戈 - 初学一级
最佳答案
我建议不要过度设计,如果使用 linq to sql 的同时要分层很清晰,那么你可以自己定义一个 Model 层。但是每个 DAL 中返回的数据都要转为这种自定义 Model 的结果了。 public ProductInfo GetProductById(int productId) { return (from p in db.Products where p.ProductID == productId select new ProductInfo { Id = p.productID, Name = p.productName }) .First(); } 返回自定义实体之后就丧失了 Linq to sql 里的实体关联了 比如你原来在 aspx 里可以绑定 <%# ((Product)Container.DataItem).Category.Name %> 现在就很难做到。 并且自己定义的 Model 层虽然可以和 linq to sql 做到比较好的隔离,但是会造成很多重复的定义。所以我不喜欢这样做,宁可还是简单一点,直接返回 linq to sql 的 entity 算了。UI 引用 DAL 就引用了吧。毕竟如何方便快速开发,并且能最大程度的减少冗余代码就是好的。 看起来美观的设计,解耦很好的设计,通常会看到一堆类似重复的废代码,真正要改的时候牵一发而动全身,何必呢。
2008/6/17 0:02:57 回答者:木野狐(Neil Chen)


提问者对于答案的评价:“如何方便快速开发,并且能最大程度的减少冗余代码就是好的” 谢谢你的回答。
其它回答(5)
感觉你的Bll层在做DAL层的事情。 如果我来设计,我会将你所说的DAL层定义为实体层。实体层的对象是能够在多个层次之间传递的。(有些时候,会将实体对象再分层,一组作为BLL和DAL通信的对象。一组作为BLL和WEB层的通信。在BLL层有一组转换器对象,进行两种实体对象的转换。这个是我看到的一个外包项目的设计,个人不理解其中的原因) 你定义中的BLL层,可以进行细分。一些简单的增删改查的元操作,应该被封装到DAL层。剩下的,和业务逻辑非常相关的逻辑,可以放在BLL层(同样是前面的那个项目中,BLL层几乎对应了WEB上的每一个按钮的点击操作,虽然我不认为这样好,但也不失为一种有效的划分层次的方式,清晰。也许在一些大型项目中反而简单有效) 最后,是WEB层,WEB层应该仅仅封装一些界面相关的逻辑,比如:展示和校验。
2个月前   回答者:Colin Han - 老鸟四级
"一组作为BLL和WEB层的通信。在BLL层有一组转换器对象,进行两种实体对象的转换", 这个就是所谓的BO和VO的区别吧~~原因就是数据库的存储与对象有差异. 要不干吗叫ORM呢~~.
2个月前   回答者:沙加 - 老鸟四级
public Product GetProductById(int productId) { Product q = (from p in db.Products where p.ProductID == productId select p).First(); return q; } 直接放在web页面,也就是.aspx.cs文件里面,世界清净了。
2个月前   回答者:金色海洋(jyk) - 菜鸟二级
@木野狐(Neil Chen) 谢谢你的回复。 如果WEB直接引用DAL。会把DAL的一些public方法同时暴露给WEB层。 当时考虑这个不太好。这样下去的话,WEB引用BLL,DAL两层了。
2个月前   回答者:[我是迭戈] - 菜鸟二级
可以定义一个自己的 Model 层,而不使用 Linq 生成的实体,创建 DataContext 也不要使用 MappingSource,而是使用 XmlMappingSource,这样就可以以非入侵的方式实现 Linq,唯一知道 Linq 的就是 BLL(实现)。 总之一句话,不要使用自动生成的实体对象。 虽然开始的时候麻烦一些,但是未来好处是是很多的;比如以后更换 DAL 的查询技术很方便。 当然,如果你的项目很简单,则没必要分层那么麻烦。
2个月前   回答者:Zealic - 初学一级
评论
2个月前   迭戈 :
要求是:Web调用的是强类型的。
2个月前   迭戈 :
@金色海洋(jyk) 。那就是WEB直接引用DAL。合理嘛。
2个月前   迭戈 :
其实我的疑问是:web中的Product按理不应该是DAL中的类。
那这个类要自己重新定一个与DAL一致的类嘛。(单单属性)
2个月前   迭戈 :
今天在CodeProject搜索到了相关的文章:
架构图如下:
http://www.codeproject.com/KB/aspnet/NTierApp_UsingLINQ/Architecture.jpg
分层比较清晰的:
Linq DAta Layer,DAL,BLL,WEB.
   您需要登录以后才能回答!
 

我要提问

我的问题


快到期问题

> 问题排行榜

相关链接