EF7 doesn't support lazy loading of child objects, ma supporta la funzione .Include()
. Detto questo, sto lottando con qualcosa e non sono sicuro che non sia possibile in EF7, o lo sto fissando da troppo tempo.ef7 non è in grado di recuperare le proprietà dell'oggetto figlio delle raccolte secondarie
qualcosa Supponiamo come il seguente (controllando reg.Activities.Task.Ordinal
(un int
), Task è sempre nullo, anche quando controllo il DB me stesso e sono certo che non v'è in realtà un record correlato) ...
public void SomeOtherMethod()
var r = getRegistration(User.UserName);
var act = r.Activities
.Where(a => a.IsDone == false) // unfinished
.OrderByDescending(o => o.Task.Ordinal) // Task indicates activity type, is always null
.FirstOrDefault(); // to get a user's most recent unfinished activity
//DO SOMETHING WITH ACT
}
public Registration getRegistration(string userName) {
var reg = _context.Registrations
.Where(r => r.User.UserName == userName) // this works however?
.Include(r => r.Acvitities) // List<Activity>
.FirstOrDefault();
return reg;
}
... Ho il navigation properties in posto nelle classi del modello, ma lo .Task
è null e non caricato.
Inoltre, dato che la query è stata progettata, non posso .Include
proprietà aggiuntive più nella creazione di act
. Non posso .ThenInclude
nella creazione di reg
perché la classe Registration
non include una definizione per una proprietà Task
(ma Registration
ha una collezione di Activities
che sono List<Activity>
, e Activity
ha un Task
che è legato ad un altro tavolo/classe che definisce il compiti e l'ordine in cui devono essere presentate agli utenti per Activity
.
ho provato vari incantesimi di .Join
, .Include
e .ThenInclude
sperando di essere in grado di aderire al Task
a ciascuno dei Activities
mentre ritorna l'oggetto Registration
, ma questo fallisce perché Registration
stesso non contiene una proprietà Task
.
Ho preso in considerazione la creazione di un nuovo problema su GitHub, ma non sono ancora sicuro che non sia molto fattibile e non lo sto guardando correttamente.
Update1: Mihail ha suggerito di utilizzare ...
.Include(r => r.Activities.Select(resp => resp.Responses))
... ma questo produce un'eccezione. Questo SO (https://stackoverflow.com/a/30151601/3246805) indica questo per EF5 e che deve essere utilizzato .ThenInclude
.
Tuttavia, cercando quel suggerimento ...
.ThenInclude(r => r.Select(t => t.Task))
... si ottiene la seguente eccezione ...
The properties expression 'r => {from Activity t in r select [t].Task}' is not valid. The expression should represent a property access: 't => t.MyProperty'. When specifying multiple properties use an anonymous type: 't => new { t.MyProperty1, t.MyProperty2 }'.
Parameter name: propertyAccessExpression
UPDATE2: Stafford ha chiesto per lo schema. Miglior risultato in un repo condivisibile ...
public class RegistrationData {
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Required]
public MyUser User { get; set; } // MyUser : IdentityUser
//blah blah, more fields
public List<UserTask> Activitys { get; set; }
}
public class UserTask {
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Required]
public bool IsDone { get; set; } = false;
[Required]
public int RegistrationId { get; set; }
[Required]
public RegistrationData Registration { get; set; }
[Required]
public int TaskId { get; set; }
[Required]
public Task Task { get; set; }
public List<UserResponse> Responses { get; set; }
}
public class Task {
[Required]
[DatabaseGenerated(DatabaseGeneratedOption.None)] // ID comes from loaded config
public int Id { get; set; }
[StringLength(20, MinimumLength = 1)]
public string Name { get; set; }
[Required]
public int Ordinal { get; set; }
[Required]
public int GroupId { get; set; }
}
public class UserResponse {
[Required]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Required]
public int UserTaskId { get; set; }
[Required]
public int QuestionNumber { get; set; }
}
si dovrebbe avere un altro riga come questa: .include (r => r.Acvitities.Select (t => t.Task)), dopo l'inclusione delle attività –
@MihailStancescu uomo che sembrava bello e Speravo che potesse risolverlo, ma sta creando un'eccezione in getRegistration quando si crea la variabile 'reg' ...'Impossibile eseguire il cast dell'oggetto di tipo 'Remotion.Linq.Clauses.Expressions.SubQueryExpression' per digitare 'System.Linq.Expressions.MemberExpression'' –