我应该继续使用Entity Framework吗?

10

我在我的新互联网Web应用程序中采用了EF(.NET 4.5的开箱即用)。

这个应用程序涉及相当多的数据库操作,并涉及大约30个或更多的表格。

我的观点是,这不是一个简单的学校项目,EF通常适用于大多数需求。

随着我进一步开发这个应用程序,我发现EF在适当/良好的数据库设计方面非常有限或具有限制性(尤其是在性能方面)

1)Include

我在查询部分遇到了Include功能。由于缺少包含设置,许多数据丢失。

我越放入这个东西,我就越担心一个简单的数据检索会在某些函数中得到比我需要的更多的东西。

2)验证

我正在采用Fluent Validation来满足这个需求,因为我喜欢访问者模式,其中不需要对数据代码本身进行直接代码更改。

但是,当我子类化时,我面临着更多的挑战,我需要解决能够遵守OOP简单内容的验证。我设法解决了它,尽管实现中存在更多复杂性和某些我真正不喜欢的东西。我相信这个子类验证问题在DataAnnotation中也会发生。

3)事务

现在,我需要整合适当的数据库事务控制,并发现EF缺少这一点,请纠正我如果我错了。

我曾经使用过企业组件(.NET中的COM+,很久以前),而且我无法找到EF中适当(或缺少)事务实现。

我仍在努力解决这个问题...

总结)

我意识到EF唯一帮助我的编码是数据/实体代码生成,这是许多其他工具/框架通用的功能。

我考虑放弃EF,回到EF之前的方法,采用存储过程,仍然是生成的表格类(但不是EF或DBML)。

我可以没有SQL LINQ,因为在过去的性能问题中,我遇到了许多挑战。

我喜欢你的意见,认为我应该坚持使用EF,除了这个ORM之外,这个ORM几乎根本没有实际工作。


在EF 6中处理事务:https://msdn.microsoft.com/zh-cn/data/dn456843.aspx - Adolfo Perez
4个回答

9
您听说过Dapper吗?它是一个超级快速的微型ORM,由Stackoverflow的开发人员(Sam Saffron)开发,他们在这个网站上广泛使用它,正如您所提到的原因一样 - 性能和速度。以下是链接:https://github.com/StackExchange/dapper-dot-net
我们放弃了EF,现在我们专门使用Dapper。结合其他社区开发的Dapper扩展,如Dapper.SimpleCRUD和Dapper.SimpleCRUD.ModelGenerator,我们可以快速地从数据库生成POCO,同时保留Dapper相对于EF的所有优势。总体而言,您将编写更多的代码,但Dapper的速度几乎等同于使用ADO.NET的SqlDataReader。以下是SimpleCRUD的链接:https://github.com/ericdc1/Dapper.SimpleCRUD/

2
我会质疑Dapper是否真正是ORM。它甚至表现为对象映射器而非全功能ORM。 - Euphoric
我一直在尝试采用Dapper,但最终也放弃了。我真的不喜欢它检索/查询数据的方式。更喜欢像LINQ那样的东西。 - Kelmen
6
这里没有一个一招制胜的解决方案。如果你使用EF,你不需要了解SQL,因为你可以使用LINQ,EF会将你的LINQ翻译成SQL查询语句。但是这种翻译是有代价的,代价就是时间。另一方面,Dapper会让你写更多的代码,并且你需要知道SQL,但你只需要编写你在应用程序中所需的内容。 - Marko
经过两年的使用,Dapper和SimpleCRUD对您来说如何运作?它们仍然是一个好选择,还是您已经找到了更好的东西?无论是更好的Dapper扩展还是其他数据访问解决方案。 - MoXplod
@MoXplod,2021年使用NPoco怎么样? - Maulik Modi

2

我同意EF在某个阶段后变得不太有用。

如果你的数据库超出了应用程序的范围,那么设计适合企业而不仅仅是应用程序的数据库。这就是EF失败的地方。它不能考虑其他需要访问数据库的人所持有的不同观点,因此你最终会得到幼稚的索引和关系。

我的两分钱(对于一个非常复杂的问题的快速回答):

编写SPs(是的,我知道)来管理数据收集,为您的业务层提供有用的数据集,并允许插入/更新底层表。但一定要确保编写一个有用的数据API,不要只为每个表编写CRUD。那是浪费时间的无意义的事情。

使用EF连接到这些SP。 EF生成有用的数据类,为您提供事务包装器以及其他许多有用的功能。

享受吧!

没有一种工具可以胜任所有任务 - 根据情况选择。


这个 EF 事务包装器是什么?你能显式地管理它吗? - Kelmen
只是这种东西。我没有真正理解术语的含义http://msdn.microsoft.com/en-us/library/vstudio/bb896325(v=vs.100).aspx并不是很令人兴奋,但它足够好用。 - LoztInSpace
@YngvarKristiansen - SP指的是存储过程。 - LoztInSpace
1
编写存储过程会很麻烦,因为您无法优化结果集,例如分页、跳过、分组等。如果您有任何优化集合结果的要求,我会避免使用存储过程。 - Jafin
@mmcrae 如果该应用程序没有包含您所做的所有部分,例如报告、批处理进程、监视器等内容,该怎么办?如果数据库已经在某种程度上存在呢?无论如何,我的观点是数据需要以自己的方式存在于应用程序之外(往往很短暂),因此不要模拟您的应用程序,而要模拟您的数据。 - LoztInSpace
@DonCheadle,您能控制表格中列的位置吗?我们定义了一个 AuditableBaseEntity,其中包含 created by、modified by,并将其继承到所有域实体中。当生成迁移时,基类列最先出现在查询中,但这些列对于检索结果或在设计视图中打开数据库表时是最不重要的。 - Maulik Modi

0

我使用Service stack的ORMlite和toptensoftware的PetaPoco创建了自己的数据访问层。

ORMlite:

1)可以从C#类创建表,包括关系、约束等(CodeFirst)

2)可以进行插入、删除、更新等操作

例如-创建表:Employee.EnsureTable()

Petapoco:

提供了很棒的SQL封装类,我使用它来代替linq

例如:sql.Select("FirstName,LastName").From("Employee").Where("ID=@0",100).AND("Active=@0",1)

我更喜欢上述风格而不是LINQ。这也支持连接(很酷吧?)

目前ORM lite不是免费的。但你可以获得旧版本,它是免费的。

例如:

//Creating Entity Class

public class Employee:DatabaseEntity<Employee>
{
    //Define properties
}

//DatabaseEntity is my own base class which provides many helper methods from ORM lite and Petapoco, including many static methods eg:EnsureTable()

//Creating Table

Employee.EnsureTable()

//Adding new entity
Employee e=new Employee();
e.FirstName="Chola"
e.LastName="Raja"
e.Active=true
e.Save()

//Find an employee
e=Employee.FirstOrDefault(x=>x.ID==101 && x.Active==true);
//OR
e=Employee.QuerySingle(sql.Select("FirstName,LastName").From("Employee").Where("ID=@0",100).AND("Active=@0",1))

//update
e.LastName="Raja"
e.Save()

//Delete a entity
e.Delete()

//Transaction
e.AssignProject(project1)  //this method could do many operation on many entities using Transaction scope

注意:我无法从我的项目中提取代码。但是,您可以根据自己的需求创建自己的基类。


0
说实话,几年前我仍然会建议任何 .net/sql 新手使用 EF,因为它的 linq 语法看起来很性感... 但这就是全部了。除此之外,你可能永远不会从 EF 中获得其他任何东西。
我知道用 C# 而不是 SQL 写代码可能在一开始听起来非常有用,但实际上并不是这样。没有任何机器生成的 SQL 可以打败你在一天结束时拥有的手工编写的 SQL 代码 :)
除此之外,EF 只会占用内存,也就是 Web 服务器的内存和 CPU,在大多数情况下是这样,但我不确定。性能和内存方面的资源消耗要多得多。
我已经完全厌倦了那个重重的 20 磅的 edmx 模型 GUI。每个表格再加一磅 :) 花费太多时间将 edmx 与实际数据库保持同步,而这一切的原因是什么呢?谁说你需要在 VS 中为你的表格添加所有那些彩色图标,真的吗?所有这些东西都只是为了让 linq-to-entities 成为可能。去他妈的,我觉得原始的 SQL 看起来一点也不比它差或不酷。

所以,我自己在一段时间前做出了一个决定 - 在我的个人项目中不使用EF。 没有沉重的错误代码,当你轻松地接受和处理它时,生活是美好的。


使用C# SQL的好处在于它非常适用于动态SQL。而传统的SQL手写编码则是一场噩梦。 - Kelmen
@Kelmen 那是你的观点。 - Justin Skiles
1
好处不仅仅是“你不必知道SQL”,你还可以免受许多繁琐的代码编写和编译时检查减少了很多错误的风险。显然存在权衡,但您的比较始于错误的前提。EF本身消耗的资源并不是非常重要的;最大的成本在于它编写的查询如果每个都手动调整,效率会更高。 - Casey

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