我应该迁移到Entity Framework吗?

7
我已经使用了SqlCommand类和自己编写的T-SQL查询很长一段时间了。我坚持使用它是因为我感到很舒服,可能是因为我开始是一个Windows开发人员,在我们拥有许多其他绝佳选择之前的时代。现在我已经做了大约10年的Web开发,仍然使用它并编写自己的查询字符串。我已经为我的所有数据库需求编写了一个动态类,我只需要编写T-SQL,我可以快速完成并在任何项目中使用。
其他开发人员看到我的代码时眼睛会变得很大,并鼓励我学习我不喜欢的LINQ。
现在我正在开始一个ASP.NET MVC项目,现在感觉应该摆脱恐龙时代,移动到实体框架中处理我的数据。
我知道SqlCommand类是Entity Framework背后的核心部件,所以我认为为什么要通过中间人(实体)来实现相同的结果并花费时间学习新东西呢?
请问有人能够解释一下为什么我需要转型,或者我应该坚持我所知道的吗?

1
在长期看来,你可能会发现,使用MVC比WebForms或标准ASP更省时间且避免了复杂性。你使用MVC的原因很可能与使用WebForms或标准ASP的原因类似吧? - rhughes
2
我会在一个样例项目中尝试使用EF。我已经很久以前(使用.NET 4.0)转向了EF,并且从未回头。EF可以为你完成80%左右的无聊编码 - 这样你就可以集中精力处理更有趣的部分! - marc_s
2
如果你喜欢编写自己的查询,并想更接近实体框架而不需要深入研究,请查看Dapper.Net(作为EF的替代方案)。 - Erik Philips
4个回答

5

转换到EF的主要原因是:

  • 一旦学会EF,开发速度更快
  • 尤其是在大多数情况下,联接操作更加简单
  • 您可以获得编译时检查,确保所有列和表实际存在
  • 你有使用EF迁移的选项,这是目前最好的数据库迁移工具之一

我多年前就转换(通过Linq2SQL),从未回头。

选择EF代码优先并使用迁移。


5

使用SqlCommand,如果你做得对的话,要么已经写了ORM的相等版本,要么你正在花费大量时间编写代码来打包参数,并将列映射到对象。如果你两者都没有做,那么很可能你有不安全的代码并且传递未类型化的数据集,然后进行大量转换,或者你正在执行危险的串联SQL查询,容易受到SQL注入攻击。

使用EF(或任何ORM)的好处在于它处理SQL生成、对象映射、参数打包,并提供一个非常强大的查询界面,让你可以快速编写多个查询。

为什么要写10行代码?当你可以只写一行时呢?

是否使用EF实际上纯粹是个人选择...但是如果你正在进行严肃的面向对象开发,你应该使用某种ORM(甚至像Dapper或Massive这样的微型ORM)。或者自己编写微型ORM。

在没有某种自动映射技术的情况下,使用ADO只会带来巨大的痛苦。


2
多年来,我一直在使用NHibernate、EntityFramework、LinqToSQL和裸的SQLCommand。ORM在生成命令的质量和所需开销方面有所不同,但它们为您的sql命令提供了简单性和类型安全性,如果您将sql编写为字符串,则无法获得这些优势。了解它们很好,因为它们是快速开发小到中型应用程序的绝佳工具,但在我看来,在大型和复杂环境中会失败。
最近,我们启动了一个新项目,并决定使用普通的SQLCommand和我们自己的Linq to SQL翻译器。对于简单的查询,它表现良好,而对于更复杂的查询,我们可以退回到专用代码中。另一件事是,我们喜欢完全控制我们的数据库,在我看来,使用ORM会失去这种控制。

我不明白如果你使用ORM,为什么不能完全控制你的数据库。你不必让ORM为你生成数据库。我从来没有这样做过。我总是先创建数据库,然后将ORM映射到它上面。 - Erik Funkenbusch
@ErikFunkenbusch 是的,那是一个选项,但是我所说的数据库不仅仅是创建或更新,还包括视图、存储过程、函数等,这些可以比从ORM中读取实体并在.NET中处理逻辑更快地完成任务。如果我没记错,EF从版本6开始可以映射视图并调用存储过程,这对他们来说是新的。 - Rafal
不,EF一直都可以调用存储过程并将结果映射回对象。在6中新增的功能是能够使用存储过程来支持映射更改以进行更新和删除。但我仍然不明白这一切与对数据库的“控制”有何关系。 - Erik Funkenbusch

1

我猜我在这个观点上会孤立无援,但是我还是要说一下。

我自己也思考过这个问题。我也是一个SqlCommand和ADO的人,而且我预计我至少还会再用一段时间。

这让我想起了LinkedIn上的一次讨论,你可能想看看这里。我相信有很多网站都在谈论这些优势,但那个帖子有几个开发者讨论了他们对此的看法。

这就是我的看法:

我倾向于编写自己的数据库访问代码,所以我走的是ADO.NET路线。我想有些人可能会称我为纯粹主义者(并不是什么好事),但我只是喜欢它给我的灵活性。我拥有完全的控制权,我知道什么会或不会工作,这可以节省查看文档的时间。实际上,我使用了一些我自己编写的包装器来做类似于Entity Framework的事情,但同时也给了我更多的控制权。不过,它仍然是建立在ADO之上的,所以我总是可以随时进去改变任何我想要的东西。

基本上,我并不认为有太多的理由去转换。我认为这不会使代码难以阅读(事实上,我喜欢冗长的选项)。通过编写自己的语句,我可以确保我的操作是正确的,并且我可以将代码直接复制到SSMS中,完全知道它在两个位置上都会执行相同的操作。
我编写的包装器提供了几个级别的访问权限,其中一个级别可以直接编写T-SQL(此处的包装器是具有类似于string.Formatparams方式输入参数的包装器),另一个级别则是建立在此之上的,可以使用半强类型代码直接构建不同类型的语句,最高级别的基于一系列属性和提示的级别则最像EntityFramework。
有时候我想使用它们中的每一个,我发现被EntityFramework和其他等效系统所限制非常令人沮丧。我想要编写自己的代码,这样我就知道出了什么问题以及如何解决它。写一个SELECT并不需要我花费太多的时间,因此使用其他方法也不会节省多少时间。
并且,正如你所说的那样, SqlCommand 不会很快消失。因此,我没有找到任何理由离开完全控制的舒适区域。

编辑:

阅读了其他几个回答后,我想我有些话要补充。我认为您已经编写了类似于我所拥有的ORM,但是如果您为每个调用编写完整的 SqlCommand 文本并即时转换所有内容,那么这很可能会导致问题。所以我一定要远离它。我倾向于喜欢拥有自己的ORM来做我想做的事情(我想一个很好的例子是,例如,如果应用程序需要,我将自动解析 XElement ,或者我将更改Sql空间数据为更易管理的内容),但是如果您的选择在于EF和不断编写与进行ADO调用相关的每一行代码之间,那么您应该切换到EF。那会带来比好处更多的危害。

编辑2:

我认为另一个需要记住的重要事情是,如果你编写自己的ORM,你需要将数据库结构与对象模型相结合。EF会保持一切同步,这很方便,但我仍然喜欢对一切有更多的控制权,而且我不介意亲自完成这项工作。

1
我很好奇,你的包装器是否创建预处理语句,以便它们被预编译,而不容易受到 SQL 注入的攻击? - Erik Funkenbusch
2
是的。即使是我的最低级包装器,它接受纯T-SQL的那个,也有可以像这样使用的函数:ExecuteNonQuery("SELECT * FROM tablename WHERE username = @p0", tbUsername.Text);。这显然是一个完全虚构的例子,但它展示了语法。基本上,我会为传入的每个对象添加参数,并使用“@p{index}”的命名约定。这使得参数化非常容易。正如我简要提到的,它与string.Format并没有太大区别,尽管使用自己的分隔符使它们更兼容。 - Matthew Haugen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接