【问题标题】:DataSets to POCOs - an inquiry regarding DAL architecture数据集到 POCO - 关于 DAL 架构的查询
【发布时间】:2011-02-20 10:46:00
【问题描述】:

我必须非常快速地开发一个相当大的 ASP.NET MVC 项目,并且我想就我的 DAL 设计获得一些意见,以确保没有任何事情会再次困扰我,因为 BL 可能会变得相当复杂。一点背景知识:我正在使用 Oracle 后端,所以内置的 LINQ to SQL 已经出来了;我还需要使用生产级库,因此 Oracle EF 提供程序项目已退出;最后,我无法使用任何 GPL 或 LGPL 代码(Apache、MS-PL、BSD 都可以),所以 NHibernate/Castle 项目退出了。我宁愿——如果可能的话——避免花钱,但我更关心实施正确的解决方案。总而言之,有我的要求:

  1. Oracle 后端
  2. 快速发展
  3. (L)无 GPL

  4. 免费

我对 DataSets 相当满意,但我会受益于使用 POCO 作为 DataSets 和视图之间的中介。谁知道呢,也许在某个时候会出现另一个 DAL 解决方案,我会抽出时间将其关闭(是的,对)。因此,虽然我可以使用 LINQ 将我的 DataSet 转换为 IQueryable,但我希望有一个通用的解决方案,这样我就不必为每个类编写自定义查询。

我现在正在修改反射,但同时我有两个问题:

  1. 此解决方案是否存在我忽略的问题?
  2. 您是否推荐其他任何将 DataSet 转换为 POCO 的方法?

提前致谢。

【问题讨论】:

  • NHibernate 不是 GPL,它是 LGPL。很大的区别。 Castle 是 Apache 2。
  • 我同意,GPL 和 LGPL 非常不同,但无法用于我的目的。我将 Castle 放在同一个句子中,因为它建立在 NHibernate 之上。
  • 这是一个很好的问题,真正触及了软件工程关键部分的核心,即如何准确安排您的 BL 和 DAL 链接。您会发现人们做事的方式不同,而且大多数人都确信他们以“正确”的方式做事。

标签: c# .net asp.net-mvc dataset poco


【解决方案1】:

没有正确答案,尽管你会发现有人会尝试给你一个答案。需要记住的一些事项:

  • 既然无法获得 EF 或 Linq-to-SQL 的优势,不用担心使用 IQuerable 接口;你不会得到它的主要优势。当然,一旦你有了 pocos,LINQ to object 将是处理它们的好方法!您的许多存储库方法将返回 IQueryable<yourType>

  • 只要你有一个好的repository来返回你的pocos,使用反射来填充它们,首先是a good strategy如果您有一个封装良好的存储库,我再说一遍。以后你总是可以切换出反射填充的实体对象代码以获得更高效的代码,而你的 BL 不会知道其中的区别。如果你让自己依赖直接反射(而不是像 nHibernate 那样optimized reflection),你以后可能会后悔效率低下。

  • 我建议查看T4 templates。几个月前,我第一次从 T4 模板生成了实体类(以及用于填充它们并保存它们的所有代码)。我被卖了!我的 T4 模板中的代码在第一次尝试时非常糟糕,但它输出了一些不错、一致的代码。

  • 您必须为存储库方法制定计划,并密切监控团队创建的所有方法。您不能使用通用的.GetOrders() 方法,因为它每次都会获得所有 客户,然后您的 LINQ to 对象看起来不错,但会覆盖一些不良数据访问!有.GetOrderById(int OrderID).GetOrderByCustomer(int CustomerID) 之类的方法。确保每个返回实体的方法至少在数据库中使用索引。如果基本查询返回 一些 被浪费的记录,那很好,但它不能进行表扫描并返回 数千 条被浪费的记录。

一个例子:

var Order = From O in rOrders.GetOrderByCustomer(CustID)    
            Where O.OrderDate > PromoBeginDate    
            Select O

在此示例中,将检索客户的所有订单,以获取 一些 订单。但是不会有很大的浪费,CustomerID当然应该是Orders上的一个索引字段。您必须决定这是否可以接受,或者是否将日期区别添加到您的存储库,无论是作为新方法还是重载其他方法。没有捷径可走。您已经在效率和维护数据抽象之间徘徊。您不希望在您的存储库中为整个解决方案中的每一个数据查询都提供一个方法。

我发现一些最近的文章,人们正在努力解决如何做到这一点。:

【讨论】:

  • 是的,我主要使用 LINQ 只是为了方便迭代。感谢您的反馈。
  • 回应编辑:我完全同意浪费的记录。我必须控制我过早优化的冲动。 T4 模板可能非常有用 - 再次感谢。
  • 最后一条评论:我不小心点击了两次投票按钮,从而撤消了投票。不幸的是,我的投票被锁定了。如果您愿意编辑您的帖子,我很乐意为您投票。
  • 更多关于组织方法的信息:stackoverflow.com/questions/2827673/…
  • 为什么,当我不明白这一点时,我没有找到这么好的解释?为了得出类似的结论,我不得不翻阅许多文章。我想我确实在这个过程中学到了很多东西......
【解决方案2】:

Devart dotConnect for Oracle 支持实体框架,然后您可以使用 LINQ to Entities。

【讨论】:

  • 我宁愿免费去,但我一定会记住这一点。谢谢。
【解决方案3】:

不必担心使用反射从数据集构建 DTO。他们工作得很好。

每个业务对象的 IComparer 实现是一个痛点。仅在表示层加载最低要求的数据。我在内存排序中严重烧伤了我的手指。

另外,提前计划在 DTO 上进行延迟加载。

我们编写了通用库来将数据表/数据行转换为实体集合/实体对象。而且它们的工作速度非常快。

【讨论】:

  • 感谢您的提示。我打算只保留最少的数据。我不确定我是否理解您所说的 DTO“工作得很好”的意思。您建议我应该为每个 POCO 编写查询而不是使用反射?这当然是合理的——我只是想尽量减少代码量。优化目前不是问题,可能暂时不会。
  • 您需要在运行时从数据集/数据表/数据行构建业务对象和这些对象的集合,以便从 biz 转发它们。层到交互层。我们使用反射来实现这种自动化。 DTO 也称为业务对象。
  • @tcg - 我不认为 DTO 和业务对象是一回事。您的业​​务对象中根本没有任何代码吗?
  • 好吧,我们还是称他们为 DTO。
猜你喜欢
  • 2019-09-18
  • 1970-01-01
  • 2014-05-25
  • 1970-01-01
  • 1970-01-01
  • 2011-02-10
  • 2010-09-28
  • 1970-01-01
  • 2014-08-28
相关资源
最近更新 更多