在基类上使用dbContext Query方法存在一些问题,该方法提供了对另一个类的某些继承(仅用于继承属性,不适用于模型/数据库构建)
在回购服务中,我称呼类似:
IEnumerable<CoasterExtended> coasters = await _db.Query<CoasterExtended>()
.FromSql(GetCoastersProcedure, pageNumberParam, pageSizeParam, orderByParam, sortParam, breweryIdParam, searchParam, coasterTypeParam)
.ToListAsync();
GetCoastersProcedure是一个SQL过程,它返回CoasterExtended类的所有属性。此类不用于模型/ db构建。它只是sql程序结果的镜像。
在我的OnModelCreating方法中,我只有:
builder.Query<CoasterExtended>();
查询sql过程的结果工作正常,直到我决定使用此类进行继承:
public class CollectionItemExtended : CoasterExtended {
// some additional properties
}
和OnModelCreating方法:
builder.Query<CollectionItemExtended>();
(CoasterExtended类型的)查询现在返回错误“'FromSql'操作的结果中没有所需的列'Discriminator'”。我知道区分符用于继承的类型,但是我使用这两个类来镜像单独的sql过程的结果(这些结果我只是映射到所需的应用程序模型类)
因此,我不想选择(和伪造)鉴别器……我只想将sql过程的结果映射到独立的类(我已经继承了,只是因为我不想复制下面的属性和映射器)。如何实现查询结果将忽略继承并仅返回描述的类型?
答案 0 :(得分:1)
问题在于基类和派生类都注册为query types,因此EF Core认为它们实现了TPH数据库继承策略(类似于普通实体类型)。
如果只想共享公共属性,请使用未注册为实体或查询类型的基类。
以您的情况为例,将CoasterExtended
类的名称更改为CoasterExtendedBase
,并让CoasterExtended
和CollectionItemExtended
都继承自该类:
public class CoasterExtended : CoasterExtendedBase { }
public class CollectionItemExtended : CoasterExtendedBase
{
// some additional properties
}
现在您可以将CoasterExtended
和CollectionItemExtended
注册为查询类型,一切都会按预期进行。
答案 1 :(得分:0)
Query
实际上在这里是多余的。这归结为FromSQL
的逻辑。换句话说,Query<Foo>.FromSQL
实际上只是FromSQL<Foo>
。简而言之,FromSQL
仅适用于实体类型,即实际映射到数据库的类型。这就是为什么它假设使用Discriminator
列进行关系继承。换句话说,这并不意味着要映射到随机的C#对象类型。
编辑
尽管上述说法是正确的,但并不全面。最好说DbSet<T>.FromSQL
必须是实体类型。 EF Core 2.1添加了对“查询集”的支持,但是您必须在上下文中定义这样的查询集才能使用它:
public DbQuery<CollectionItemExtended> CollectionItemExtendeds { get; set; }
然后,您可以在其上使用FromSQL
:
_context.CollectionItemExtendeds.FromSQL(...);