内存数据库中的 Dbset returns 具有空集合导航的实体 属性
Dbset of in memory database returns entity with empty collection navigation property
测试的问题:
[Fact]
public async Task CountOfDaysOffInCurrentYearToToday()
{
var application1 = new Domain.Entities.Application
{
Type = ApplicationType.DayOff, Status = ApplicationStatus.Approved, StatedDates =
{
new ApplicationDate { Date = new DateTime(2021, 4, 1) },
new ApplicationDate { Date = new DateTime(2022, 4, 1) },
new ApplicationDate { Date = new DateTime(2023, 4, 1) }
}
};
var application2 = new Domain.Entities.Application
{
Type = ApplicationType.DayOffAtExpenseOfVacation, Status = ApplicationStatus.Approved, StatedDates =
{
new ApplicationDate { Date = new DateTime(2021, 4, 1) },
new ApplicationDate { Date = new DateTime(2022, 4, 1) },
new ApplicationDate { Date = new DateTime(2023, 4, 1) }
}
};
var application3 = new Domain.Entities.Application
{
Type = ApplicationType.DayOffAtExpenseOfVacation, Status = ApplicationStatus.Approved, StatedDates =
{
new ApplicationDate { Date = new DateTime(2021, 4, 1) },
new ApplicationDate { Date = new DateTime(2022, 4, 1) },
new ApplicationDate { Date = new DateTime(2023, 4, 1) }
}
};
var user = new AppUser
{
ApplicantApplications = { application1, application2, application3 }
};
var context = GetDbContext();
await context.Users.AddAsync(user);
await context.SaveChangesAsync();
var bl = new UserCalendarBL(context, GetDateTime());
Assert.Equal(4, await bl.CountOfDaysOffInCurrentYearToToday(user.Id));
}
我调试的时候显示StatedDates
在每个应用中都是空的:
private static IDbContext GetDbContext()
{
var options = new DbContextOptionsBuilder<AppDbContext>()
.UseInMemoryDatabase(new StackFrame(1, true).GetMethod()!.Name)
.Options;
return new AppDbContext(options);
}
private IDateTimeService GetDateTime()
{
var mock = new Mock<IDateTimeService>();
mock.Setup(e => e.Now()).Returns(new DateTime(2022, 5, 1));
return mock.Object;
}
这些是实体类型:
public class Application
{
public int Id { get; set; }
public AppUser Applicant { get; set; }
public string ApplicantId { get; set; }
public DateTime DateOfCreation { get; set; }
public DateTime? DateOfSent { get; set; }
public ApplicationType Type { get; set; }
public ApplicationStatus Status { get; set; }
public List<ApplicationDate> StatedDates { get; set; } = new List<ApplicationDate>();
public AppUser Coordinator { get; set; }
public string CoordinatorId { get; set; }
public string Comment { get; set; }
}
public class AppUser : IdentityUser
{
public List<Application> ApplicantApplications { get; set; } = new List<Application>();
public List<Application> CoordinatorApplications { get; set; } = new List<Application>();
public string FullName { get; set; }
public string Position { get; set; }
public int? CountOfUnusedVacationDaysOverPastYears { get; set; }
}
public class ApplicationDate
{
public DateTime Date { get; set; }
public int ApplicationId { get; set; }
public Application Application { get; set; }
}
ApplicationDate
具有 Date
和 ApplicationId
的组合键
这些是测试方法:
public async Task<int> CountOfDaysOffInCurrentYearToToday(string userId)
{
return await Task.Run(() =>
{
var applications = ApprovedApplicationsInCurrentYearToToday(userId).AsParallel().Where(
application =>
application.Type == ApplicationType.DayOff ||
application.Type == ApplicationType.DayOffAtExpenseOfVacation ||
application.Type == ApplicationType.DayOffAtExpenseOfWorkingOut).ToImmutableArray();
return applications.Sum(CountOfApplicationDatesInCurrentYearToToday);
});
}
private IEnumerable<Domain.Entities.Application> ApprovedApplicationsInCurrentYearToToday(string userId)
{
return _context.Applications
.Include(application => application.Applicant)
.AsNoTracking()
.AsParallel()
.Where(application =>
application.Applicant.Id == userId &&
GetApplicationStatedDates(application)
.Any(date => date.Year == _dateTime.Now().Year && date < _dateTime.Now()));
}
在 where 方法中,通过在断点处停止,我可以验证 StatedDates
是否为空。
您必须像这样显式加载导航 属性 StatedDates
:
private IEnumerable<Domain.Entities.Application> ApprovedApplicationsInCurrentYearToToday(string userId)
{
return _context.Applications
.Include(application => application.Applicant)
.Include(application => application.StatedDates)
.AsNoTracking()
.AsParallel()
.Where(application =>
application.Applicant.Id == userId &&
GetApplicationStatedDates(application)
.Any(date => date.Year == _dateTime.Now().Year && date < _dateTime.Now()));
}
测试的问题:
[Fact]
public async Task CountOfDaysOffInCurrentYearToToday()
{
var application1 = new Domain.Entities.Application
{
Type = ApplicationType.DayOff, Status = ApplicationStatus.Approved, StatedDates =
{
new ApplicationDate { Date = new DateTime(2021, 4, 1) },
new ApplicationDate { Date = new DateTime(2022, 4, 1) },
new ApplicationDate { Date = new DateTime(2023, 4, 1) }
}
};
var application2 = new Domain.Entities.Application
{
Type = ApplicationType.DayOffAtExpenseOfVacation, Status = ApplicationStatus.Approved, StatedDates =
{
new ApplicationDate { Date = new DateTime(2021, 4, 1) },
new ApplicationDate { Date = new DateTime(2022, 4, 1) },
new ApplicationDate { Date = new DateTime(2023, 4, 1) }
}
};
var application3 = new Domain.Entities.Application
{
Type = ApplicationType.DayOffAtExpenseOfVacation, Status = ApplicationStatus.Approved, StatedDates =
{
new ApplicationDate { Date = new DateTime(2021, 4, 1) },
new ApplicationDate { Date = new DateTime(2022, 4, 1) },
new ApplicationDate { Date = new DateTime(2023, 4, 1) }
}
};
var user = new AppUser
{
ApplicantApplications = { application1, application2, application3 }
};
var context = GetDbContext();
await context.Users.AddAsync(user);
await context.SaveChangesAsync();
var bl = new UserCalendarBL(context, GetDateTime());
Assert.Equal(4, await bl.CountOfDaysOffInCurrentYearToToday(user.Id));
}
我调试的时候显示StatedDates
在每个应用中都是空的:
private static IDbContext GetDbContext()
{
var options = new DbContextOptionsBuilder<AppDbContext>()
.UseInMemoryDatabase(new StackFrame(1, true).GetMethod()!.Name)
.Options;
return new AppDbContext(options);
}
private IDateTimeService GetDateTime()
{
var mock = new Mock<IDateTimeService>();
mock.Setup(e => e.Now()).Returns(new DateTime(2022, 5, 1));
return mock.Object;
}
这些是实体类型:
public class Application
{
public int Id { get; set; }
public AppUser Applicant { get; set; }
public string ApplicantId { get; set; }
public DateTime DateOfCreation { get; set; }
public DateTime? DateOfSent { get; set; }
public ApplicationType Type { get; set; }
public ApplicationStatus Status { get; set; }
public List<ApplicationDate> StatedDates { get; set; } = new List<ApplicationDate>();
public AppUser Coordinator { get; set; }
public string CoordinatorId { get; set; }
public string Comment { get; set; }
}
public class AppUser : IdentityUser
{
public List<Application> ApplicantApplications { get; set; } = new List<Application>();
public List<Application> CoordinatorApplications { get; set; } = new List<Application>();
public string FullName { get; set; }
public string Position { get; set; }
public int? CountOfUnusedVacationDaysOverPastYears { get; set; }
}
public class ApplicationDate
{
public DateTime Date { get; set; }
public int ApplicationId { get; set; }
public Application Application { get; set; }
}
ApplicationDate
具有 Date
和 ApplicationId
这些是测试方法:
public async Task<int> CountOfDaysOffInCurrentYearToToday(string userId)
{
return await Task.Run(() =>
{
var applications = ApprovedApplicationsInCurrentYearToToday(userId).AsParallel().Where(
application =>
application.Type == ApplicationType.DayOff ||
application.Type == ApplicationType.DayOffAtExpenseOfVacation ||
application.Type == ApplicationType.DayOffAtExpenseOfWorkingOut).ToImmutableArray();
return applications.Sum(CountOfApplicationDatesInCurrentYearToToday);
});
}
private IEnumerable<Domain.Entities.Application> ApprovedApplicationsInCurrentYearToToday(string userId)
{
return _context.Applications
.Include(application => application.Applicant)
.AsNoTracking()
.AsParallel()
.Where(application =>
application.Applicant.Id == userId &&
GetApplicationStatedDates(application)
.Any(date => date.Year == _dateTime.Now().Year && date < _dateTime.Now()));
}
在 where 方法中,通过在断点处停止,我可以验证 StatedDates
是否为空。
您必须像这样显式加载导航 属性 StatedDates
:
private IEnumerable<Domain.Entities.Application> ApprovedApplicationsInCurrentYearToToday(string userId)
{
return _context.Applications
.Include(application => application.Applicant)
.Include(application => application.StatedDates)
.AsNoTracking()
.AsParallel()
.Where(application =>
application.Applicant.Id == userId &&
GetApplicationStatedDates(application)
.Any(date => date.Year == _dateTime.Now().Year && date < _dateTime.Now()));
}