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

本文关键字:对象 属性 子集合 ef7 检索 | 更新日期: 2023-09-27 18:27:17

EF7不支持子对象的延迟加载,但支持.Include()函数。话虽如此,我正在为一些事情而挣扎,不确定这在EF7中是不可能的,还是我已经盯着这个看了太久了。

假设如下所示(检查reg.Activities.Task.Ordinal(一个int),Task始终为null,即使我自己检查了DB,并且确信实际上存在相关记录)。。。

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;
}

我在模型类中有适当的导航属性,但上面的.Task为null并且未加载。

此外,由于查询已经被投影,在创建act时,我不能再.Include附加属性了。我不能在创建reg时使用.ThenInclude,因为类Registration不包括Task属性的定义(但Registration确实有一个Activities的集合,它们是List<Activity>,而Activity确实有一个子Task,它与另一个表/类相关,该表/类定义了任务以及每个Activity应向用户显示任务的顺序。

我尝试了.Join.Include.ThenInclude的各种咒语,希望能够在返回Registration对象的同时将Task连接到每个Activities,但这失败了,因为Registration本身不包含Task属性。

我曾考虑在GitHub上创建一个新问题,但还不确定它是否不太可行,我只是没有正确看待这一点。


更新1:米海尔建议使用
.Include(r => r.Activities.Select(resp => resp.Responses))
……但这产生了一个例外。此SO(https://stackoverflow.com/a/30151601/3246805)指示EF5是这样的,并且应当使用CCD_ 26。

然而,尝试这个建议
.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



更新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; }
}

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

使用IncludeThenInclude作为子属性。ThenInclude的子属性可能不会显示在intelligense中,但只要输入它就可以了——它将按预期编译和操作。

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;