Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/294.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 实体框架代码优先-从表中选择对象,其中对象的类型在预定义列表中_C#_Entity Framework - Fatal编程技术网

C# 实体框架代码优先-从表中选择对象,其中对象的类型在预定义列表中

C# 实体框架代码优先-从表中选择对象,其中对象的类型在预定义列表中,c#,entity-framework,C#,Entity Framework,使用实体框架,我有一个类的层次结构,这些类映射到同一个表。比如猫:动物,狗:动物,山羊:动物 当然,EF在内部使用鉴别器列来处理它们 现在,我想写一些类似的东西: var houseAnimals = new List<Type>(new [] { typeof(Cat), typeof(Dog) }); this.dataRepository.Animals.Where(a => houseAnimals.Contains(a.GetType())); 我不想做一个is C

使用实体框架,我有一个类的层次结构,这些类映射到同一个表。比如猫:动物,狗:动物,山羊:动物

当然,EF在内部使用鉴别器列来处理它们

现在,我想写一些类似的东西:

var houseAnimals = new List<Type>(new [] { typeof(Cat), typeof(Dog) });
this.dataRepository.Animals.Where(a => houseAnimals.Contains(a.GetType()));
我不想做一个is Cat | | is Dog,因为这个列表是在运行时动态构建的

基于,我了解到EF将把它转换为SQL查询,该查询具有“Discriminator in”语句。所以,这给了我一些希望,我所需要的可以做到。这:

this.dataRepository.Animals.Where(a => a is **in** houseAnimals);
这很好,但是当然没有这样的语法

问题是,我可以使用什么语法来实现这一点?我是不是遗漏了什么?这是EF中缺少的功能吗?我不可能是唯一一个想做这种询问的人


基于这个例子,请不要把我的方法和进行这个查询的需要简单化,因为我已经简化了很多,只是为了解释我需要什么。Doing.ToList也不是一个选项。

EF不提供这种现成的功能。但编写一个自定义扩展方法并不难,它可以借助和动态构建谓词,如下所示:

public static class QueryableExtensions
{
    public static IQueryable<T> OfType<T>(this IQueryable<T> source, IEnumerable<Type> types)
    {
        var parameter = Expression.Parameter(typeof(T), "a");
        var body = types
            .Select(type => Expression.TypeIs(parameter, type))
            .Aggregate<Expression>(Expression.OrElse);
        var predicate = Expression.Lambda<Func<T, bool>>(body, parameter);
        return source.Where(predicate);
    }
}

如果我是你,我会对鉴别器列感到非常厌倦,并且只在你真的需要的时候才使用它们。SQL有关系-主键和外键-尝试使用这种继承映射可能会导致各种问题。我不显式使用鉴别器列。好的,让我重新表述一下-我会非常厌倦在SQL中使用C对象继承映射。这是EF代码首先工作的默认方式。包管理器控制台为我生成SQL脚本,它决定为我的类和鉴别器使用一个表。我没有资格批评它;我知道我应该避免像+1这样的评论,但我必须说这是一个令人印象深刻的解决方案,它对我很有效。我在使用您的代码时遇到问题-没有方法“OfType”的重载包含1个参数。答案中的方法是带有一个参数的OfType。确保扩展方法在需要它的地方可见。i、 e.使用{包含上述类的命名空间};。
public static class QueryableExtensions
{
    public static IQueryable<T> OfType<T>(this IQueryable<T> source, IEnumerable<Type> types)
    {
        var parameter = Expression.Parameter(typeof(T), "a");
        var body = types
            .Select(type => Expression.TypeIs(parameter, type))
            .Aggregate<Expression>(Expression.OrElse);
        var predicate = Expression.Lambda<Func<T, bool>>(body, parameter);
        return source.Where(predicate);
    }
}
this.dataRepository.Animals.OfType(houseAnimals);