实体框架核心包含与子类不同的属性

Tum*_*hir 3 c# asp.net entity-framework-core

我的类和存储库的结构:

public class Group{
    //fields
}

public class User{
    public UserRole Role {get;set;}
}

public abstract class UserRole{
    //fields
}

public class PersonUserRole:UserRole{
    public Group Group {get;set;}
}

public class ManagerUserRole:UserRole{
    public IList<Group> Groups {get;set;}
}
Run Code Online (Sandbox Code Playgroud)

我遇到问题的示例:

public class UserRepository:IUserRepository{
    private readonly ApplicationDbContext _dbContext;
    private readonly DbSet<User> _users;

    public UserRepository(ApplicationDbContext dbcontext)
    {
        _dbContext = dbcontext;
        _users = _dbContext.DomainUsers;
    }

    public User GetBy(int id)
        {
            User type = _users.Include(u => u.Role)
                              .SingleOrDefault(c => c.UserId == id);
            if (typeof(PersonUserRole) == type.Role.GetType())
            {
                return
                    _users.Include(u => u.Role)
                        .ThenInclude(r => (r as PersonUserRole).Groep)
                        .SingleOrDefault(c => c.UserId == id);
            }
            else
            {
                return _users.Include(u => u.Role)
                             .ThenInclude(r => (r as ManagerUserRole).Groups)
                             .SingleOrDefault(c => c.UserId == id);
            }
        }
}
Run Code Online (Sandbox Code Playgroud)

我收到以下错误消息:

消息“属性表达式'r =>(r作为PersonUserRole).Group'无效。该表达式应表示对属性的访问:'t => t.MyProperty'

看来我无法将我的UserRole类型转换PersonUserRole为包含Group / Groups属性的实际类型。如何包含子类的属性?

Iva*_*oev 5

更新:从2.1版开始,EF Core自然通过在lambda / 重载或重载内的强制转换或运算符来自然支持派生类型上的IncludeasIncludeThenIncludestring Include

原始答案(EF Core 2.1之前的版本):

当前不支持紧急加载派生实体导航属性。

解决方法是,可以结合使用Eager加载显式加载查询 EF Core文档的“ 加载相关数据”部分中说明的相关实体

var user = _users.Include(u => u.Role).SingleOrDefault(u => u.UserId == id);
var userRoleQuery = db.Entry(user).Reference(u => u.Role).Query();
if (user.Role is ManagerUserRole)
    userRoleQuery.OfType<ManagerUserRole>().Include(r => r.Groups).Load();
else if (user.Role is PersonUserRole)
    userRoleQuery.OfType<PersonUserRole>().Include(r => r.Group).Load();
return user;
Run Code Online (Sandbox Code Playgroud)