c# - 为什么没有 EF Core OfType(Type type) 方法?
问题描述
我目前使用的是 EF Core 3.0。所以,我想通过基表请求来实现TPH模型数据的选择。让我们看看这个例子:
public class BaseClass
{
public int Base {get;set;}
}
public class Foo : BaseClass
{
public int FooMember {get;set;}
}
public class Bar : BaseClass
{
public int BarMember {get;set;}
}
public DbSet<BaseClass> dbSet {get;set;}
我想实现这样的代码:
var getInheritedSet = dbSet.OfType(typeIStronglyNeed);
但我只能做这样的事情:
var getInheritedSet1 = dbSet.OfType<Foo>;
var getInheritedSet2 = dbSet.OfType<Bar>;
您能解释一下为什么 EF Core 3.0 没有OfType(Type type)
但只有OfType<TType>()
吗?
第二个问题 - 如何从 DbSet 获取继承的数据类型?
谢谢你。
解决方案
泛型方法OfType<T>
是 EF Core 支持的标准 LINQ 方法。
没有标准OfType(Type)
方法,EF Core 设计人员也没有找到实现这种自定义 EF Core 特定扩展的理由。
但实施起来并不难。TPH(和其他未来的数据库继承策略)在 LINQ to Entities 查询中由is
和运算符支持。所以你需要的是相当于as
cast
Where((BaseClass e) => e is some_type)
这样的表达式不能在编译时创建,但可以使用Expression
类方法(特别是Expression.TypeIs)轻松创建,如下所示:
public static IQueryable<T> OfType<T>(this IQueryable<T> source, Type type)
{
var parameter = Expression.Parameter(typeof(T), "e");
var body = Expression.TypeIs(parameter, type);
var predicate = Expression.Lambda<Func<T, bool>>(body, parameter);
return source.Where(predicate);
}
第二个问题 - 如何从 DbSet 获取继承的数据类型?
EF Core 元数据通过DbContext.Model
属性公开。您可以使用FindEntityType
来获取IEntityType
描述实体类型
var entityType = dbContext.Model.FindEntityType(typeof(BaseClass));
现在有很多关于继承的可用方法,如, ,GetDerivedTypes
等GetDerivedTypesInclusive
。最后一个可用于检索不包括抽象类型的整个 TPH 层次结构。并获取 TPH 中每个实体的鉴别器列名称、类型和值。例如GetDirectlyDerivedTypes
GetConcreteDerivedTypesInclusive
GetDiscriminatorProperty
GetDiscriminatorValue
var discriminatorProperty = entityType.GetDiscriminatorProperty();
var typeInfo = entityType
.GetConcreteDerivedTypesInclusive()
.Select(t => new
{
Type = t,
DiscriminatorValue = t.GetDiscriminatorValue()
})
.ToList();
推荐阅读
- php - 我想要两个相等部分的变量
- javascript - HTML:选中复选框时使元素不可见
- sapui5 - 表中的最大列数 (20+) - SAP UI5
- apache-spark - SPARK 无法使用 AWS Kinesis 流
- c# - 比较 C#/Unity 中的列表并忽略项目
- reactjs - 如何在 React-Navigation-3 中设置应用容器?
- node.js - 在 Puppeteer 中禁用下载
- c# - 在c#中从标签名称包含冒号(:)的xml元素中读取值
- discord - discord.js 出于某种原因,此命令下的任何代码都不起作用?
- json - 带引号的 Json paser 输出