急切加载的数据错误说上下文已经处理

Eager loaded data errors saying context already disposed

编辑 Driver class 根据要求:

public class Driver
{
    public int Id { get; set; }
    public ApplicationUser User { get; set; }
    public string DriverDirectoryTitle { get; set; }
    public string FullNames { get; set; }
    public string AlternatePhoneNumber { get; set; }
    public string IdNumber { get; set; }
    public DateTime DateOfBirth { get; set; }
    public DateTime RegistrationDate { get; set; }
    public Gender Gender { get; set; }
    public Ethnicity Ethnicity { get; set; }
    public bool Disability { get; set; }
    public string Address { get; set; }
    public City City { get; set; }
    public string Nationality { get; set; }
    public bool OwnVehicle { get; set; }
    public bool DriversLicense { get; set; }
    public Experience Experience { get; set; }
    public string Availability { get; set; }
    public Vehicle Vehicle { get; set; }
    public bool IsPremium { get; set; }
    public bool Deleted { get; set; }
}

问题

我的应用有点像 Euro Truck Simulator 的东西,它列出了工作的司机。

我正在 return 将 DTO 添加到我的页面(顺便说一句,这是 ASPX Web 窗体),它与 Driver 数据模型密切相关:

public class DriverViewModel
{
    public int Id { get; set; }
    public string UserId { get; set; }
    public string FullNames { get; set; }
    public string DriverDirectoryTitle { get; set; }
    public string RegistrationDate { get; set; }
    public string AlternatePhoneNumber { get; set; }
    public string IdNumber { get; set; }
    public DateTime DateOfBirth { get; set; }
    public Ethnicity Ethnicity { get; set; }
    public Experience Experience { get; set; }
    public City City { get; set; }
    public Gender Gender { get; set; }
    public List<DriverLicensesViewModel> LicenseCodes { get; set; }
    public Vehicle Vehicle { get; set; }
    public bool Disability { get; set; }
    public string Address { get; set; }
    public string Nationality { get; set; }
    public bool OwnVehicle { get; set; }
    public bool DriversLicense { get; set; }
    public string Availability { get; set; }
    public bool IsPremium { get; set; }
    public bool ReferenceChecked { get; set; }
    public bool PoliceClearance { get; set; }
}

请注意,none 的关系属性定义为 virtual - 因此 none 的数据被延迟加载。

在 return 页面上的视图模型之前,我正在做一些工作,但特别是,只有一些关系属性的映射导致以下错误。

这是映射代码:

using (var db = new ApplicationDbContext())
{
    var drivers = db.Drivers
        .Include(x => x.User).Include(x => x.City)
        .Include(x => x.Ethnicity).Include(x => x.Experience)
        .Include(x => x.Gender).Include(x => x.Vehicle)
        .OrderBy(x => x.FullNames).ToList();

    var driverModels = new List<DriverViewModel>();
    foreach (var driver in drivers)
    {
        var driverModel = new DriverViewModel
        {
            Id = driver.Id,
            FullNames = driver.FullNames,
            DriverDirectoryTitle = driver.DriverDirectoryTitle,
            RegistrationDate = driver.RegistrationDate.ToString("ddd, dd MMM yyy"),
            AlternatePhoneNumber = driver.AlternatePhoneNumber,
            IdNumber = driver.IdNumber,
            DateOfBirth = driver.DateOfBirth,
            Ethnicity = driver.Ethnicity,
            Experience = driver.Experience,
            Gender = driver.Gender,
            Vehicle = driver.Vehicle,
            Disability = driver.Disability,
            Address = driver.Address,
            Nationality = driver.Nationality,
            OwnVehicle = driver.OwnVehicle,
            DriversLicense = driver.DriversLicense,
            Availability = driver.Availability,
            IsPremium = driver.IsPremium,
            LicenseCodes = new List<DriverLicensesViewModel>()
        };
    }
}

此处显示的代码工作正常,数据完美加载到页面上,但是,如果我将城市 属性 的映射添加到映射中,则会发生错误:

The ObjectContext instance has been disposed and can no longer be used for operations that require a connection.

我已经检查了其他一些问题,例如下面链接的问题,但似乎都涉及延迟加载数据,而我显然没有这样做:

那么,为什么我在此处添加的城市关系会导致问题,而其他关系的 none 会导致问题,我该如何解决?

如果树中的任何实体包含 virtual 属性,它们将被 Entity Framework 延迟加载,而不仅仅是根实体。

似乎 City 确实包含 virtual 属性,因此一旦首次访问它们(即在您的映射中),它将导致对数据库的另一个 SQL 查询必要的数据。

如果你的上下文被释放,这将失败,所以解决方案是删除 virtual 关键字,或者使用 Select:

预先加载
db.Drivers
    .Include(x => x.City.Select(c => c.LazyProperty));

为了完整起见,对于 EF Core,这将是:

db.Drivers
    .Include(x => x.City)
        .ThenInclude(c => c.LazyProperty);