如果我忽略用于某个过程的 dbset,我将无法使用 EF Core 来获取该过程

dja*_*azz 5 c# entity-framework entity-framework-core ef-core-2.2

我有一个运行良好的 EF Core 2.2 应用程序。然后我介绍程序并知道我可以这样做:

...在我的上下文中

public virtual DbSet<MyProcsDbSet> MyProcsDbSet{ get; set; }
Run Code Online (Sandbox Code Playgroud)

获取数据的示例调用:

using(var context = myContext())
{
   var data = context.MyProcsDbSet.ExecuteSQL("Myproc @p0", 1);
}
Run Code Online (Sandbox Code Playgroud)

应该注意这可以正常工作。但是,当我创建一个新的迁移时,它会生成一个表。很好,没什么大不了的,我只是在模型创建中声明不构建该表。

bldr.Ignore<MyProcsDbSet>();
Run Code Online (Sandbox Code Playgroud)

不,现在当我调用正在运行的程序时,我得到了这个:

无法为“MyProcsDbSet”创建 DbSet,因为此类型未包含在上下文的模型中。

有没有办法为过程返回获取 dbset 而不必永远抑制 ef core 创建表的需要? .NET Core EF 代码的能力似乎总是最大的缺点是自定义对象及其创建和检索。

Iva*_*oev 7

Ignore(或[NotMapped]属性)绝对不是为了抑制表生成。它基本上是告诉 EF Core 不要将类及其属性视为模型的一部分,因此它不能用于 LINQ to Entities 查询和其他 EF Core 提供的服务。

在 EF Core 2.x 中实现目标的唯一选择是将 SP 结果类映射为查询类型

除了实体类型之外,EF Core 模型还可以包含查询类型,这些类型可用于对未映射到实体类型的数据执行数据库查询。

查询类型有一些限制,但同时默认情况下不会映射到数据库对象,因此非常适合与FromSql.

您所需要的只是将定义从 更改DbSetDbQuery

public virtual DbQuery<MyProcsDbSet> MyProcsDbSet{ get; set; } 
Run Code Online (Sandbox Code Playgroud)

如果您有流畅的配置,请确保使用modelBuilder.Query<MyProcsDbSet>而不是modelBuilder.Entity<MyProcsDbSet>.


在 EF Core 3.0 中,上述内容将发生变化,因为查询类型将与实体类型合并。所以基本上你必须将DbSet(和modelBuilder.Entity)与HasNoKey流畅的 API结合使用。现在说确切的行为是什么还为时过早,但我希望无键实体类型(他们在 3.0 中称之为)默认情况下不会映射到表,或者会有一个特殊的流畅 API 来告诉实体没有关联表。这在 2.x 中很有用 - 正如我在开头提到的那样,Ignore具有不同的含义,因此使用类似HasNoTable(), or [Table(null)], 或 之类的东西.ToTable(null)来显式抑制表生成会很好。

但它就是这样,所以要么使用查询类型,要么从生成的迁移中手动删除“表”和相关命令。