BT

如何利用碎片时间提升技术认知与能力? 点击获取答案

Entity Framework Core 2.0的槽点

| 作者 Jonathan Allen 关注 593 他的粉丝 ,译者 薛命灯 关注 24 他的粉丝 发布于 2017年8月24日. 估计阅读时间: 6 分钟 | QCon上海2018 关注大数据平台技术选型、搭建、系统迁移和优化的经验。

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

评价本文

专业度
风格

您好,朋友!

您需要 注册一个InfoQ账号 或者 才能进行评论。在您完成注册后还需要进行一些设置。

获得来自InfoQ的更多体验。

告诉我们您的想法

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我
社区评论

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

讨论

登陆InfoQ,与你最关心的话题互动。


找回密码....

Follow

关注你最喜爱的话题和作者

快速浏览网站内你所感兴趣话题的精选内容。

Like

内容自由定制

选择想要阅读的主题和喜爱的作者定制自己的新闻源。

Notifications

获取更新

设置通知机制以获取内容更新对您而言是否重要

BT