La struttura delle mie classi e repository:
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;}
}
Un esempio in cui ho riscontrato il problema:
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);
}
}
}
Ottengo il seguente messaggio di errore:
Messaggio "L'espressione della proprietà 'r => (r As PersonUserRole) .Group" non è valido. L'espressione dovrebbe rappresentare un accesso alla proprietà:' t => t.MyProperty '
Sembra che non possa UserRole
mio tipo PersonUserRole
al tipo PersonUserRole
effettivo per includere la proprietà Group / Groups. Come posso includere le proprietà delle sottoclassi?
Aggiornamento: a partire dalla versione 2.1, l' inclusione sui tipi derivati è ora supportata naturalmente da EF Core tramite cast o as
operatore all'interno di lambda Include
/ ThenInclude
overload o string
Include
overload.
Risposta originale (pre EF Core 2.1):
Attualmente il caricamento impaziente delle proprietà di navigazione delle entità derivate non è supportato.
Come soluzione alternativa, è possibile utilizzare una combinazione di caricamento Eager , caricamento esplicito e entità correlate alla query spiegate nella sezione Caricamento dei dati correlati della documentazione di 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;
EntityFramework ha un problema aperto che è esattamente lo stesso del tuo problema: https://github.com/aspnet/EntityFramework/issues/3910
Forse puoi provare quello che suggeriscono, ma non posso provare se funziona:
var o = context.Set<Order>() .Where(o => o.Id == 1234) .Single(); context.Set<GroupPosition>() .Where(x => x.Order == o) .Include(x => x.GroupType) .Load(); context.Set<SalesPosition>() .Where(x => x.Order == o) .Include(x => x.Group) .Load();