我是否应该担心ORM默认返回所有列?

时间:2011-03-03 05:16:59

标签: nhibernate entity-framework orm entity-framework-4 llblgenpro

由于我在使用ORM(迄今为止LLBL Gen Pro和Entity Framework 4)方面的经验有限,我注意到本质上,查询会返回所有列的数据。我知道NHibernate是另一种流行的ORM,我不确定这是否适用,但我认为它确实适用。

当然,我知道有解决方法:

  • 创建SQL视图并在视图上创建模型和映射
  • 使用存储过程并在返回的结果集上创建模型和映射

我知道坚持某些做法可以帮助减轻这种情况:

  • 确保您的行数在选择数据时受到合理限制
  • 确保您的表格不会过宽(大量列和/或大数据类型)

所以这是我的问题:

  1. 上述做法是否足够,或者我是否仍应考虑寻找限制返回列数的方法?

  2. 除了上面列出的列之外,还有其他方法可以限制返回的列吗?

  3. 您通常如何在项目中处理此问题?

  4. 提前致谢。

    更新:这种情况源于SELECT *被认为是一种不良做法的观念。请参阅this discussion

7 个答案:

答案 0 :(得分:8)

使用几乎任何类型的ORM的原因之一是延迟了许多较低级别的问题,并专注于业务逻辑。只要您保持连接合理且桌面宽度合理,ORM就可以轻松地将数据输入和输出,并且需要整个行可用。

就我个人而言,在遇到因桌面宽度而陷入困境的特定情况之前,我会考虑这种过早优化的问题。

答案 1 :(得分:2)

第一个:很好的问题,关于时间有人问这个! :-)

是的,ORM通常会返回数据库表的所有列,这是设计系统时需要考虑的事项。但正如你所提到的 - 有很多方法可以解决这个问题。

对我来说,主要的事实是意识到这就是发生的事情 - SELECT * FROM dbo.YourTable或(更好)a SELECT (list of all columns) FROM dbo.YourTable

当你真正想要整个对象及其所有属性时,这不是问题,只要你加载几行,那也没关系 - 方便性优于原始性能。

您可能需要考虑更改数据库结构 - 例如:

  • 可能会将像BLOB这样的大型列放到单独的表中,并使用1:1链接到基表 - 这样,父表上的select就不会抓取所有那些大块的数据

    < / LI>
  • 可能会将可选的列组(可能仅在某些情况下显示)放入单独的表中并链接它们 - 再次,只是为了保持基表的精简程度

另外:避免试图“掰手”你的ORM进行批量操作 - 这不是他们的强项。

并且:密切注意性能,并尝试选择一个ORM,允许您将某些操作更改为例如存储过程 - 实体框架4允许这样做。因此,如果删除操作正在扼杀您 - 也许您只需为该表编写一个Delete存储过程并以不同方式处理该操作。

答案 2 :(得分:1)

问题here相当适合您的选择。基本上你只限于手工制作HQL / SQL。如果遇到可伸缩性问题,这是你想要做的事情,但如果按照我的经验做,它可以产生非常大的积极影响。特别是,它节省了大量磁盘和网络IO,因此您的可扩展性可能会大幅提升。不过马上就可以做了:分析然后优化。

答案 3 :(得分:1)

  

除了上面列出的列之外,还有其他方法可以限制返回的列吗?

NHibernate允许您向查询添加投影,因此您不需要仅使用视图或过程来限制列。

答案 4 :(得分:0)

对我而言,如果表格中有很多列&gt;这只是一个问题。 30或者如果该列有很多数据,例如字段中有超过5000个字符。

我使用的方法是将另一个对象映射到现有表,但只包含我需要的字段。因此,对于填充100行的表的搜索,我会有一个 MyObjectLite,但是当我单击以查看该行的详细信息时,我将调用GetById并返回包含所有列的MyObject。

另一种方法是使用自定义SQL,Stroed触发器,但我认为如果你真的需要性能提升并让用户抱怨,你应该走这条路。因此,除非存在性能问题,否则不要浪费时间来解决不存在的问题。

答案 5 :(得分:0)

您可以使用Projection和Transformers.AliasToBean和DTO来限制返回列的数量,以及它在Criteria API中的外观:

.SetProjection(Projections.ProjectionList()
    .Add(Projections.Property("Id"), "Id")
    .Add(Projections.Property("PackageName"), "Caption"))
.SetResultTransformer(Transformers.AliasToBean(typeof(PackageNameDTO)));

答案 6 :(得分:0)

在LLBLGen Pro中,您可以返回Typed Lists,它不仅允许您定义返回的字段,还允许您连接数据,以便从多个表中提取字段的自定义列表。

总的来说,我同意在大多数情况下,这是过早的优化。

使用LLBLGen和其他ORM的一大优势(我只是自信地谈论LLBLGen,因为我从一开始就使用它)是数据访问的性能已经被了解问题的人们优化了比你的平均熊更好。

每当他们找到进一步加快代码速度的方法时,只需重新生成数据层或安装新的dll,即可“免费”获得这些更改。

除非您认为自己是编写数据访问代码的专家,否则ORM可能会提高大多数开发人员的效率和准确性。