如何在EF Core 3.0中使用数据库视图?

时间:2019-09-28 03:48:08

标签: ef-core-3.0

我知道之前曾有人问过这个问题,但当时我们有了EF Core2.x。简短的回答是“不行”,显然不是很有帮助。

其他答案涉及丑陋的骇客,例如在使用该工具创建迁移文件后更改它们。

我首先编写应用程序代码。我在创建模型时考虑了很多外键和数据库联接。

但是这带来了令人不愉快的惊喜(我对EF有点陌生):用LINQ编写的那些联接非常慢,因为事实上它们不产生数据库联接,而是获取整个表。

当然,这完全是不可接受的,我导入了一个具有数百万条记录的旧数据库,其中的联接以毫秒为单位获得结果,而我却没有几秒钟的滞后-在我非常快速的Internet连接上(在实际情况下,更糟)。

我需要视图,而AFAIK EF不会为我创建视图,对于EF 3.0还是如此吗?

然后,在SQL中创建视图并为其创建实体的最佳,最简洁的方法是什么?我的意思是-考虑到数据库模型会随时间变化的情况,并且必须更新数据库结构。

好吧,我宁愿不在SQL视图中进行联接,只是让查询返回“ JOIN”语句结果。特别是一些不明显的联接。可以说表B的一列是引用表A的外键。我想从连接B的表A中获取结果,以获取详细信息。具有正常的SQL JOIN性能。

我检查了数据库:“ select * from A”和“ select * from A join B ...”之间没有明显的性能差异。在LINQ中-差异很大。

1 个答案:

答案 0 :(得分:0)

我发现在Code First中,数据库视图是多余的。 可以将“视图”创建为模型(普通类),该模型具有将字段或属性设置为所连接实体的模型。我为此使用专用字段。然后,我使用LINQ Join()创建我的视图实体。该查询仅可引用设置为已连接实体的字段,仅此而已。这种查询(如果编写得当的话)可以清楚地转换为SQL JOIN并可以全速运行。在我的应用程序中,它等效于数据库视图。

您可能会问为什么是私有字段而不是属性。也许因为联接的实体是“实现细节”,但是另一个原因是我的演示文稿代码使用反射对实体的公共属性进行操作,因此最好将那些实体隐藏在其中。否则,我可能需要使用属性来隐藏那些“列”。

顺便说一句,此类视图可以使用OrderBy()进行排序,可以使用Where()进行过滤,而几乎是免费的。约束是保持集合的IQueryable接口,切勿间接引用联接的实体。因此,即使X引用了A.B,也从未在X查询中引用LINQ,总是A.B,其中A是在{{1 }}查询。

要在运行时构建动态查询,必须使用表达式。

这组EF Core 3.0属性允许在不使用SQL的情况下构建数据库应用程序,但保持完整的SQL速度。但是,数据库/实体的结构必须相对简单才能实现。