@xuemingdeng
2017-08-22T09:18:51.000000Z
字数 2274
阅读 733
.NET
摘要:
Entity Framwork(EF)一直以来毁誉参半,有些人喜欢它,不过有些人认为它与NHibernate、LINQ-to-SQL和其他小型ORM框架相比没有什么优势。EF Core在早期给人们留下糟糕的印象,也一直让那些对EF有所期待的人大失所望。
正文:
Entity Framwork(EF)一直以来毁誉参半,有些人喜欢它,不过有些人认为它与NHibernate、LINQ-to-SQL和其他小型ORM框架相比没有什么优势。EF Core在早期给人们留下糟糕的印象,也一直让那些对EF有所期待的人大失所望。
SQL生成
EF最糟糕的一点是对SQL生成这一功能支持不足,而EF Core 2.0仍然不支持最基本的SQL组建功能(比如group)。虽说ORM框架不支持一些高级特性(如Window Functions)是很正常的,但无法处理像“GROUP BY”这样的功能对于大部分开发者来说是无法接受的。
版本说明里提到,这一版本“增加了一些SQL映射模式,之前版本里很多会触发客户端求值的查询在2.0里不会再有类似的行为”。不过,他们并没有提及这些模式的具体细节,所以我们建议开发者要小心对待每一个查询。当然,你也可以禁用客户端求值。
微软方面指出,他们计划在EF Core 2.1里支持group特性。
复杂类型(Complex Type)
EF里有复杂类型的概念,开发者可以创建映射到同一张表的子对象。它的用处之一就是用来把常用的审计字段和一般的数据字段分开。
EF Core并不支持复杂类型,不过它提供了“Owned”和“Child”类型。微软的Diego B Vega说,“EF Core 2.0的Owned类型支持之前EF版本的复杂类型所能支持的所有场景”。不过,它们的语法不太一样,而且模型设计得太过复杂,需要花更多的时间来学习它们。
懒加载
懒加载被很多人认为是一个糟糕的设计,因为它会导致性能问题(比如1+N查询问题)和运行时错误(比如上下文被销毁)。尽管如此,它仍然是EF里非常受欢迎的一个特性,有些人认为,如果一个ORM框架不支持这一特性,那么它就算不上一个真正的ORM框架。所以把懒加载推迟到EF Core 2.1这一决定也难怪会让他们感到不安。
微软的Rowan Miller说开发者可以创建自己的懒加载机制。
虽然2.0不支持懒加载,不过我们提供了一些特性,可以通过这些特性来实现懒加载。其中最重要的一个就是Life Cycle Hooks,再结合我们在1.1版本里就已引入的EntityEntry API,就可以实现一个初步的懒加载。
不过,用于具体化对象的Life Cycle Hooks目前还只是EF Core 2.1的“延展目标”。
Table Per Type
Table Per Type(TPT)继承模式可以让一个逻辑记录跨越多个数据库表。一个抽象的基类代表一张表,而每一个子类都有自己对应的表。这样一来,在数据库设计上就会更有效率,而应用程序也能看到数据的逻辑视图。
不过,TPT在EF里有严重的性能问题。以下的抱怨内容来自User Voice。
随着子类数量的增长,生成SQL需要花费更长时间,SQL查询也变得越来越复杂,难以管理。一个简单的基类(5到6个字段)和大约30个左右的简单子类(2到3个字段)就需要2分钟来生成和执行(ObjectQuery.ToTraceString())。EF会为基类的一个简单SELECT查询生成8000行SQL代码,生成的SQL里有很多子查询、join和union。即使是空表(查询不返回数据),它也需要那么多时间来生成和执行SQL。
这里的大部分问题都已经得到修复,不过EF 6已经过时了,微软在这方面也没有计划投入更多的资源。
EF Core完全不支持TPT,尽管这一特性已经包含在backlog里,但并没有具体的实现计划。这对于已经在EF里使用TPT的开发者来说会是个问题,因为他们需要作出重大修改。
Table Per Concrete Class
与TPT相关的另一个特性是TPC,也就是Table Per Concrete Class。与TPT类似,它也是通过继承关系来简化类的设计。不过,在数据库端并没有相应的表来表示抽象基类。每一个具体的子类与自己的一张表相对应,这张表包含了子类本身和所有父类的字段。
EF Core也不支持TPC,不过似乎没有太多人对此提出看法,可能是因为开发者可以很容易地使用接口来代替抽象基类。基类的属性可以被剪切和拷贝到子类里,虽然这样做很繁琐,但也并没有什么问题。
存储过程
另一个缺失的特性是对存储过程的支持。尽管存储过程有可能被滥用,但对于关系型数据库来说,它仍然是一个强大的工具。在很多情况下,直接在数据库端处理数据要比把数据传送到应用程序里再处理高效得多。特别是当一个事务需要锁定多个表,并多次传送数据的时候,存储过程的优势就更为明显。
这个特性看起来似乎是很容易实现的,因为生成这样的SQL非常简单。InfoQ通过DLR来演示一个小型ORM仅使用了200行代码。不过,目前这一特性也只是在backlog中,没有具体的实现计划。
因为有临时解决方案的存在,所以这一特性的优先级不会很高。Anuraj P演示了如何在EF Core里调用存储过程,以及如何解决缺乏命名参数的痛点。
空间类型
EF Core不支持空间数据,虽然它的路线图赋予这一特性较高的优先级,但并没有具体的发布计划。
查看英文原文: Entity Framework Core 2.0 Released to Heavy Criticism