EF Core:具有包含List的属性的类,在获取DbSet时将列表返回为null



我有一个DbSet,它包含类"周";。类中的属性之一是包含类"的列表;天";。

public class Week
{
[Key]
public int Id { get; set; }
public List<Day> Days { get; set; }
public bool Ferie { get; set; }
public int WeekNo { get; set; }
public int Year { get; set; }
}
public class Day
{
[Key]
public int Id { get; set; }
public List<ProjectTask> Tasks { get; set; }
public DateTime Date { get; set; }
public int AvailableHours { get; set; }
public int HoursLeftToBook { get; set; }
public string? DayName { get; set; }
public int Priority { get; set; }
}

数据库的设置如下,包括迁移。我在更改后创建了一个新闻迁移,所以数据库应该是最新的。

public class ApplicationDbContext : IdentityDbContext
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
Database.Migrate();
}
public DbSet<Week> Weeks { get; set; }
}

目前,我正在从控制器中测试数据库。首先,我加载mockdata,将其保存到数据库中,然后再次从数据库中加载数据,以便在页面上显示。

public IActionResult Index()
{
PlannerViewModel plannerViewModel = new();

var mock = _plannerService.MockData();

// Save to database
_dataService.SaveWeeks(_plannerService.AssignProjects(mock));
// Get from database
plannerViewModel.Weeks = _dataService.GetWeeks();
return View(plannerViewModel);
}

保存和返回表格的方法,供参考:

public void SaveWeeks(List<Week> weeks)
{
_db.Weeks.AddRange(weeks);
_db.SaveChanges();
}
public List<Week> GetWeeks()
{
return _db.Weeks.ToList();
}

加载时,周在页面上显示良好,并包含正确的日期。之后,我注释掉获得模拟数据并将其保存到数据库的行,因为模拟数据已经添加。就行"_dataService。GetWeeks(("保留(当然还有viewModel代码(,然后重新运行项目。现在仍然可以正确地从数据库中提取周数,但突然间,每周的天数列表为空。我检查了数据库,在两次运行之间没有任何变化。关系是否连接不正确?如果是这样的话,为什么它第一次有效,而不是第二次?

这可能是因为获取数据的方法并不急于用.Include加载相关数据。当您调用将实体添加到DbContext的数据时,该DbContext将跟踪那些新添加的实体以及与它们一起添加的任何相关实体。当您从DbContext读取顶级实体(周(时,即使您没有急切地加载子实体(天(,由于DbContext已经在跟踪天,它仍然会填充这些子关系。

第二次是依赖数据库中已有的数据。DbContext不是跟踪这些实体,所以当您获得dbContext.Weeks.ToList()时,您将只获得Weeks,而没有相关的天数。

当您在获取对象图时期望相关数据时,请确保:

A( 总是急于加载相关数据:

var weeks = dbContext.Weeks.Include(w => w.Days).ToList();

B( 依靠投影在不需要实体的地方获得所需数据:

var weekDetails = dbContext.Weeks
.Select(w => new WeekDetailViewModel
{
Id = w.Id,
WeekNo = w.WeekNo,
Days = w.Days.Select(d => new DayDetailViewModel
{
Id = d.Id,
// ...
}).ToList()
}).ToList();

最新更新