是否可以在 Entity Framework 核心版本 2.1 上自动映射数据库视图?
Is it possible to automatically map a DB view on Entity Framework Core version 2.1?
我发现 关于映射视图并在 EF Core 中使用它。
根据 ,以前的 EF Core 版本无法自动映射视图。
但是现在呢?根据 Entity Framework 2.1 Roadmap,
An EF Core model can now include query types. Unlike entity types,
query types do not have keys defined on them and cannot be inserted,
deleted or updated (i.e. they are read-only), but they can be returned
directly by queries. Some of the usage scenarios for query types are:
- Mapping to views without primary keys
- (...)
所以问题是:是否可以自动构建数据库上下文并映射其视图(就像我们为 a normal scaffold-dbcontext 对现有数据库所做的那样)?如果是,有人知道怎么做吗?
或者唯一的方法仍然是 ,正如 Sampath Kaliyamurthy 在之前的 EF Core 版本的回答中所说的那样?
变通解决方案:
我找到了一个解决方法,其中包括:
- 重命名视图(例如从 "MyView" 更改为 "My_View")
- 使用
select * into table from view
查询从该视图创建一个 table,并将其命名为视图初始名称(例如,table 将被命名为 "MyView")
- 在table中设置一个主键
- Scaffold the DB,所以你得到所有的类和正确的映射
- 从映射描述符中删除
HasKey
属性
- 从数据库中删除 table 并使用其初始名称重命名视图(因此,再次从 "My_View" 更改为 "MyView")
这将使视图像普通脚手架一样工作 table,您将获得所有正确的映射和所有内容。
当然,唯一的区别是您无法向其中插入数据或对其进行编辑。
但没关系,因为如果您想使用视图,您从一开始就知道这一点!
但是
考虑这个问题仍然开放...
...尽管有这种解决方法,我仍然想知道是否还有更多 "immediate" 和“2.1-native”,正如他们在路线图中所说的那样,随着 ef 2.1 引入。
所以任何帮助 and/or 答案将不胜感激!
可以搭建一个视图。只需像构建 table 的脚手架一样使用 -Tables,仅使用视图的名称。例如,如果您的视图名称是“vw_inventory”,那么 运行 程序包管理器控制台中的此命令(用您自己的信息替换“我的...”):
PM> Scaffold-DbContext "Server=MyServer;Database=MyDatabase;user id=MyUserId;password=MyPassword" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Temp -Tables vw_inventory
此命令将在项目的 Temp 目录中创建模型文件和上下文文件。您可以将模型文件移动到您的模型目录中(记得更改命名空间名称)。您可以从上下文文件中复制您需要的内容并将其粘贴到项目中适当的现有上下文文件中。
注意:如果您想在使用本地数据库的集成测试中使用您的视图,您需要在数据库设置中创建视图。如果您要在多个测试中使用该视图,请确保添加对视图是否存在的检查。在这种情况下,由于 SQL 'Create View' 语句需要成为批处理中的唯一语句,因此您需要 运行 create view as dynamic Sql within the existence检查语句。或者,您可以 运行 分开“如果存在则删除视图...”,然后是“创建视图”语句,但是如果多个测试同时 运行,您不希望在另一个测试时删除视图正在使用它。
示例:
void setupDb() {
...
SomeDb.Command(db => db.Database.ExecuteSqlRaw(CreateInventoryView()));
...
}
public string CreateInventoryView() => @"
IF OBJECT_ID('[dbo].[vw_inventory]') IS NULL
BEGIN EXEC('CREATE VIEW [dbo].[vw_inventory] AS
SELECT ...')
END";
这很有帮助 link。它描述了手动添加代码部分而不是搭建它们:https://docs.microsoft.com/en-us/ef/core/modeling/keyless-entity-types?tabs=fluent-api
我发现
根据
但是现在呢?根据 Entity Framework 2.1 Roadmap,
An EF Core model can now include query types. Unlike entity types,
query types do not have keys defined on them and cannot be inserted,
deleted or updated (i.e. they are read-only), but they can be returned
directly by queries. Some of the usage scenarios for query types are:
- Mapping to views without primary keys
- (...)
所以问题是:是否可以自动构建数据库上下文并映射其视图(就像我们为 a normal scaffold-dbcontext 对现有数据库所做的那样)?如果是,有人知道怎么做吗?
或者唯一的方法仍然是
变通解决方案:
我找到了一个解决方法,其中包括:
- 重命名视图(例如从 "MyView" 更改为 "My_View")
- 使用
select * into table from view
查询从该视图创建一个 table,并将其命名为视图初始名称(例如,table 将被命名为 "MyView") - 在table中设置一个主键
- Scaffold the DB,所以你得到所有的类和正确的映射
- 从映射描述符中删除
HasKey
属性 - 从数据库中删除 table 并使用其初始名称重命名视图(因此,再次从 "My_View" 更改为 "MyView")
这将使视图像普通脚手架一样工作 table,您将获得所有正确的映射和所有内容。
当然,唯一的区别是您无法向其中插入数据或对其进行编辑。
但没关系,因为如果您想使用视图,您从一开始就知道这一点!
但是
考虑这个问题仍然开放...
...尽管有这种解决方法,我仍然想知道是否还有更多 "immediate" 和“2.1-native”,正如他们在路线图中所说的那样,随着 ef 2.1 引入。所以任何帮助 and/or 答案将不胜感激!
可以搭建一个视图。只需像构建 table 的脚手架一样使用 -Tables,仅使用视图的名称。例如,如果您的视图名称是“vw_inventory”,那么 运行 程序包管理器控制台中的此命令(用您自己的信息替换“我的...”):
PM> Scaffold-DbContext "Server=MyServer;Database=MyDatabase;user id=MyUserId;password=MyPassword" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Temp -Tables vw_inventory
此命令将在项目的 Temp 目录中创建模型文件和上下文文件。您可以将模型文件移动到您的模型目录中(记得更改命名空间名称)。您可以从上下文文件中复制您需要的内容并将其粘贴到项目中适当的现有上下文文件中。
注意:如果您想在使用本地数据库的集成测试中使用您的视图,您需要在数据库设置中创建视图。如果您要在多个测试中使用该视图,请确保添加对视图是否存在的检查。在这种情况下,由于 SQL 'Create View' 语句需要成为批处理中的唯一语句,因此您需要 运行 create view as dynamic Sql within the existence检查语句。或者,您可以 运行 分开“如果存在则删除视图...”,然后是“创建视图”语句,但是如果多个测试同时 运行,您不希望在另一个测试时删除视图正在使用它。 示例:
void setupDb() {
...
SomeDb.Command(db => db.Database.ExecuteSqlRaw(CreateInventoryView()));
...
}
public string CreateInventoryView() => @"
IF OBJECT_ID('[dbo].[vw_inventory]') IS NULL
BEGIN EXEC('CREATE VIEW [dbo].[vw_inventory] AS
SELECT ...')
END";
这很有帮助 link。它描述了手动添加代码部分而不是搭建它们:https://docs.microsoft.com/en-us/ef/core/modeling/keyless-entity-types?tabs=fluent-api