ef7无法检索子集合的子对象的属性

t.j*_*.j. 5 c# entity-framework asp.net-core-mvc asp.net-core

EF7不支持延迟加载子对象,但支持该.Include()功能.话虽这么说,我正在努力解决一些问题,我不确定它是否在EF7中是不可能的,或者我只是盯着这个太久了.

假设如下所示(check reg.Activities.Task.Ordinal(an int),Task始终为null,即使我自己检查数据库并且确定实际上存在相关记录)...

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;
}
Run Code Online (Sandbox Code Playgroud)

...我在模型类中有导航属性,但.Task上面是null并且未加载.

此外,由于已经预测了查询,因此.Include在创建时我不能再有其他属性了act.我不能.ThenInclude在创作中reg,因为类Registration不包含一个定义Task属性(但Registration确实有一个集合的ActivitiesList<Activity>,和Activity它有一个Task是与另一台/类定义的任务和应提交的顺序每个用户Activity.

我已经尝试了各种各样的咒语.Join,.Include.ThenInclude希望能够在返回对象时加入Task到每个中,但是这会失败,因为它本身不包含属性.ActivitiesRegistrationRegistrationTask

我考虑在GitHub上创建一个新问题,但我还不确定它是不是很可行而且我只是没有正确地看待它.


UPDATE1: Mihail建议使用......
.Include(r => r.Activities.Select(resp => resp.Responses))
但是这会产生异常.这个SO(/sf/answers/2110612101/)表示EF5 .ThenInclude应该使用的那个.

但是,尝试这个建议
.ThenInclude(r => r.Select(t => t.Task))
......会产生以下例外......

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
Run Code Online (Sandbox Code Playgroud)



更新2:斯塔福德要求架构.在可共享的回购中尽最大努力......

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; }
}
Run Code Online (Sandbox Code Playgroud)

Sta*_*ams 12

使用Include后跟ThenInclude孩子的孩子属性.子属性可能不会出现在intellisense中ThenInclude,但只是输入它 - 它将按预期编译和操作.

var reg = _context.Registrations
  .Where(r => r.User.UserName == userName)
  .Include(r => r.Acvitities).ThenInclude(a => a.Task)
  .Include(r => r.Activities).ThenInclude(a => a.SomethingElse)
  .FirstOrDefault();
  return reg;
Run Code Online (Sandbox Code Playgroud)

  • 更新后的建议中的`a.SomethingElse`是上面提供的架构中的`List <UserResponse> Responses`.当我点到点然后"别的东西"(`Responses`)时,我只得到`IEnumberable`函数/方法的列表(例如:`Count`,`Capacity`,`Select`,`Where`等) (2认同)