使用代码优先实体框架过滤多个派生类

发布于 2024-12-11 19:08:00 字数 1113 浏览 0 评论 0原文

假设我有一个 User 和 2 个派生实体 StudentTeacher。我使用了 TPH 方法,所以我的班级中实际上没有任何属性可以告诉我谁是老师或不是老师。

我有 2 个布尔值,应该允许我加载学生或教师,如下所示:

//IQueryable<User>
var query = userRepository.GetUsers();

//Type filtering
if (searchModel.IsStudent)
{
    query = query.OfType<Student>();
}
if (searchModel.IsTeacher)
{
    query = query.OfType<Teacher>();
}

当尝试评估时,当两者都为 true 时,我会收到此错误:

DbIsOfExpression 需要一个具有与以下内容兼容的多态结果类型的表达式参数类型参数。

我已经在 SO 上查看了一些答案,但它们面向 1 种类型的过滤。

然后我想做这样的事情(粗略编码):

if(query.ToList().FirstOrDefault() is Student)
{
     print "student";
}

映射:

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<User>()
                    .Map<Teacher>(m => m.Requires("UserType").HasValue("Teach"))
                    .Map<Student>(m => m.Requires("UserType").HasValue("Stu"))
                    .Map<Staff>(m => m.Requires("UserType").HasValue("Staff"));
    }

Lets say I have a User with 2 derived entities Student, Teacher. I used the TPH method, so I actually have no property at all in my classes to tell me who is a teacher or not.

I have 2 booleans that should allow me to load either student or teacher such as this:

//IQueryable<User>
var query = userRepository.GetUsers();

//Type filtering
if (searchModel.IsStudent)
{
    query = query.OfType<Student>();
}
if (searchModel.IsTeacher)
{
    query = query.OfType<Teacher>();
}

When this tries to evaluate, I get this error when both are true:

DbIsOfExpression requires an expression argument with a polymorphic result type that is compatible with the type argument.

I already looked at some answers here on SO but they are geared towards 1 type of filtering.

I would then like to do something like this (rough coding):

if(query.ToList().FirstOrDefault() is Student)
{
     print "student";
}

The mapping:

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<User>()
                    .Map<Teacher>(m => m.Requires("UserType").HasValue("Teach"))
                    .Map<Student>(m => m.Requires("UserType").HasValue("Stu"))
                    .Map<Staff>(m => m.Requires("UserType").HasValue("Staff"));
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

汹涌人海 2024-12-18 19:08:00

试试这个。它至少适用于 EF 5。

IQueryable<User> Filter(this IQueryable<User> query, 
    bool includeTeacher, bool includeStudent)
{

  return query.Where(x => includeTeacher && x is Teacher
                || includeStudent && x is Student);
}

Try this one. It works at least for EF 5.

IQueryable<User> Filter(this IQueryable<User> query, 
    bool includeTeacher, bool includeStudent)
{

  return query.Where(x => includeTeacher && x is Teacher
                || includeStudent && x is Student);
}
三生路 2024-12-18 19:08:00

这很丑陋,但它可以满足您的需要:

if (searchModel.IsStudent && searchModel.IsTeacher) 
{
    var result = context.Users.OfType<Teacher>()
                        .Cast<User>()
                        .Union(context.Users.OfType<Student>());
}

并且它将在一个查询上运行! :)

This is ugly but it will work for what you need:

if (searchModel.IsStudent && searchModel.IsTeacher) 
{
    var result = context.Users.OfType<Teacher>()
                        .Cast<User>()
                        .Union(context.Users.OfType<Student>());
}

And It will run on one query!! :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文