这是问题的简化(有许多方法可以做),但在需要与数据库交谈的应用程序中,我经常看到两种模式中的一种:
这两种方法的主要区别之一是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系统通常会在“引擎盖下”进行额外的数据库访问,以填充外键等等,这可能会为不知情的事件带来问题。
您通常偏爱哪种方法?为什么?
答案 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相比的优势(虽然它们可以很好用,但它们并不是必需的。)
仅转换一次数据。在我看过的DataTable-crunching应用程序中,有很多内容遍布:
if(row [“col”] == DBNull.Value || string.IsNullOrEmpty(row [“col”] as string))...
在填充数据对象时,我宁愿检查一次这个条件,而不是在使用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个小步骤
答案 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解决方案提供了我所需要的所有东西,并且比我以前的解决方案简单得多。