本土ORM与DataTables?

时间:2008-11-07 11:25:31

标签: .net orm datatable

这是问题的简化(有许多方法可以做),但在需要与数据库交谈的应用程序中,我经常看到两种模式中的一种:

  1. 对象关系映射(ORM),其中(通常)数据库中的每个表都有一个对应的“行包装器”类,其公共属性与表中的列相匹配。有时这些类还会自动检索相关信息,以便外键列可以显示为相关数据(而不仅仅是PK值)。
  2. DataTables(和/或DataSets),其中数据作为DataTable从服务器检索并以该形式使用(即使在UI中)。
  3. 这两种方法的主要区别之一是ORM允许您在代码中引用强类型字段,如下所示:

    Person bob = new Person();
    bob.FirstName = "Bob";
    collectionPeople.Add(bob);
    

    而使用DataTable方法,您的代码将类似于:

    DataRow newrow = datatablePeople.NewRow();
    newrow["FirstName"] = "Bob";
    datatablePeople.Rows.Add(newrow);
    

    在这种情况下,ORM方法受益于编译时检查,而DataTable方法则没有。另一方面,DataTable(和DataSet)是已经编写的数据结构,可以很好地直接表示关系数据,因此使用它们的代码通常可以更快地实现。此外,使用DataTables的代码可以被其他人轻松理解和修改;自行开发(通常是COTS)ORM系统通常会在“引擎盖下”进行额外的数据库访问,以填充外键等等,这可能会为不知情的事件带来问题。

    您通常偏爱哪种方法?为什么?

8 个答案:

答案 0 :(得分:8)

在使用数据时,Datatable在概念上肯定会更直接。而且它在ORM中找不到有时不自然的习语。 (在更新之前将记录查询到本地内存;连接是指针;键值本身是指针,因此,添加记录需要加载父记录)

ORM的巨大优势是......

1)它为你编写sql,所以你真的不必编写任何sql来做基本的crud。当然,编写更复杂的语句必须在功能较弱的子语言(即hql)

中完成

2)ORM的另一大优势是,当您获得结果时,它会将其映射到值对象,而无需编写大量代码来映射值并处理类型转换。

如果你有强大的sql技能,但想要优势2覆盖,我会选择ibatis

答案 1 :(得分:7)

我赞成DataTables的方式,因为我老了,累了,对像Subsonic和Linq这样的时尚持怀疑态度。

除此之外,当您使用ORM时,通常会最大限度地减少在SQL中执行的操作。您没有在SQL中添加大量逻辑,也没有批处理多个SQL语句,以便在一次数据库中执行多项操作。因此,您倾向于更频繁地访问数据库,这是一个很大的性能损失。

使用数据集,我可以这样做:

从表1中选择col1,col2 .... 从表2中选择col1,col2 .... 从table3中选择col1,col2 ...

然后使用Tables [0],Tables [1],Tables [2]进行数据库的一次访问以获取所有三个DataSet,以引用它们。它在性能上有很大的不同。

有一天,与数据库的交互可能会如此之快,以至于没有必要对SQL进行批处理,但那一天还没有到来。当它到来时,我将切换到ORM,但在那之前,我愿意让我的代码变得更加丑陋以换取性能。用户使用缓慢的应用程序并不好玩。

最后,我喜欢SQL。我擅长SQL。真棒。我不想花时间弄清楚如何让Linq发出我想要的SQL。它会减慢 MY 的表现。

答案 2 :(得分:4)

您可以结合使用Strongly Typed DataSets提及的两种方法。

可以通过“添加新项”对话框“DataSet模板”将它们添加到Visual Studio项目中,然后使用可视数据集设计器(它在后台编辑XSD文件)。

主题还有另外article

答案 3 :(得分:4)

在.Net中,强类型数据集具有ORM的优点 - 在IDE和Intellisense中强类型的值,

在Visual Studio中创建的TableAdapter将为您编写所有CRUD SQL。您将业务逻辑放在C#(或其他语言)中而不是SQL中。

我认为数据集提供的断开连接的数据模型在实践中证明比典型的手工编码SQL更有效。它会导致非繁琐的数据库交互,您可以在一个查询中获得所有相关的表数据。它对乐观锁定(提供DBConcurrency异常)有很好的支持。数据集还跟踪数据的插入,修改和删除,因此您不必这样做。

强类型数据集还提供对相关表数据的直接导航。

关于DataSet的一个很好的参考是

  

编程Microsoft®ADO.NET2.0   David Sceppa的核心参考资料

     

发布者:Microsoft Press Pub日期:   2006年5月17日打印ISBN-10:   0-7356-2206-X打印ISBN-13:   978-0-7356-2206-7页数:800

+汤姆

答案 4 :(得分:3)

我会看一下数据对象与DataTables相比的优势(虽然它们可以很好用,但它们并不是必需的。)

  • 概念上干净。您被迫将OO概念应用于您的数据。更容易理解“这是一个人”而不是“我想要的人就在这张桌子的某个地方”。
  • 强制分离关注点。将UI上下文数据粘贴到DataTable是很诱人的 - 对于一个UI,我得到一个具有相同记录中的主要地址的Person,另一个我在同一记录中获得具有信用信息的Person。当我使用模型时,我希望无论在何处使用它,该模型都是一致的。
  • 仅转换一次数据。在我看过的DataTable-crunching应用程序中,有很多内容遍布:

    if(row [“col”] == DBNull.Value || string.IsNullOrEmpty(row [“col”] as string))...

    在填充数据对象时,我宁愿检查一次这个条件,而不是在使用DataTable的地方检查它。

  • 更容易进行单元测试。如果引用不存在的数据对象中的字段,则会出现编译时错误。如果引用DataTable中不存在的字段,则会出现运行时错误。

我相信ORM会让你变得懒惰。例如,如果始终一起使用这些对象,则绝对没有理由从对象中的各个查询填充一组相关数据对象。相反,编写一个大而有效的查询来获取所有必要的数据,然后构建数据对象图。尽管如此,如果你记住它的局限性,它确实可以节省很多工作。

相关:How to convince my co-workers not to use datasets for enterprise development (.NET 2.0+)

答案 5 :(得分:2)

我曾经在.NET早期使用DataSet,然后开始使用类型化DataSet,随着时间的推移发现DataSet留下的内存占用非常高,并且对每个简单任务使用非托管对象都没有意义。
因此得出结论,DTO / POCO是更好的选择,并开始使用NHibernate和iBatis  我的平均(或低于平均水平)开发人员发现它们很复杂且难以使用(没有双关语意)。
所以我做了一个本土种植的 ORM XmlDataMapper,它更容易使用复杂的ORM出现在那里。

要集成XmlDataMapper,您需要做的只有4个小步骤

  1. 为表格创建业务实体/ DTO
  2. 使用表格和DTO之间的映射信息创建XML文件。
  3. 在配置中指定DTO和xml文件。
  4. 只需调用DTOConverter.Convert(dataReader)和其他此类方法将您的数据库记录转换为DTO / Business Entity

答案 6 :(得分:0)

我曾经只是使用一个datareader来使用GetString,GetInt等将字段读取到我的对象上,但我现在转向使用Gateway从查询返回数据表的更多OO和可测试方法,这是然后传递到Service类,该类将表解析为一个对象。

我从不真正喜欢ORM工具,它们总是很麻烦且难以维护,但我没有机会玩LINQ,所以我的意见可能会改变。

答案 7 :(得分:0)

我发现使用ORM而不是DataSets / DataTables,我能够开发更少的代码并更好地测试我的代码。我目前正在使用LINQ-to-SQL,并通过部分类作为我的ORM在设计器生成的代码周围包裹一个薄层。薄层基本上允许我添加一些基于角色的权限,并通过重构接口和使用依赖注入来指定数据上下文来增加代码的可测试性(这样我可以将其模拟为其他测试)。

我已经完成了两项工作 - 围绕DS / DT编写我自己的ORM,强类型DS / DT等等,并且已切换到LINQ并且不会再回头了。我最终可能转向NHibernate,Entity Framework或其他类似的东西,但是现在我的LINQ解决方案提供了我所需要的所有东西,并且比我以前的解决方案简单得多。