即使在调用 ToList 后仍出现 ObjectContext 错误

Getting ObjectContext error even after calling ToList

直接在下方调用方法时,使用检索到的列表调用 Mapper.Map 时出现 ObjectDisposedException。

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

public IEnumerable<Models.Provider> Get(string owner)
{
    List<Data.Models.Provider> providers;

    using (var db = new Data.ProviderDirectoryContext())
    {
        providers = db.Providers.Where(p => p.Owner.Name == owner).ToList();
    }

    var dtoProviders = Mapper.Map<List<Data.Models.Provider>, List<Models.Provider>>(providers);
    return dtoProviders;
}

我以前有这样的代码(如下),我没有收到错误,但是在进行映射时数据库受到冲击,而且花费的时间太长。我不想在做映射时访问数据库。

public IEnumerable<Models.Provider> Get(string owner)
{
    using (var db = new Data.ProviderDirectoryContext())
    {
        var providers = db.Providers.Where(p => p.Owner.Name == owner).ToList();
        var dtoProviders = Mapper.Map<List<Data.Models.Provider>, List<Models.Provider>>(providers);
        return dtoProviders;
    }
}

如何在进行映射之前检索所有数据?

这里是 DbContext 和 Data.Models.Provider 供您参考。

public class ProviderDirectoryContext : DbContext
{
    public DbSet<Owner> Owners { get; set; }

    public DbSet<Location> Locations { get; set; }
    public DbSet<LocationAuditLog> LocationAuditLog { get; set; }

    public DbSet<Office> Offices { get; set; }
    public DbSet<OfficePhoneNumber> OfficePhoneNumbers { get; set; }
    public DbSet<OfficeAuditLog> OfficeAuditLog { get; set; }
    public DbSet<OfficeDay> OfficeDays { get; set; }

    public DbSet<Provider> Providers { get; set; }
    public DbSet<ProviderPhoneNumber> ProviderPhoneNumbers { get; set; }
    public DbSet<ProviderAuditLog> ProviderAuditLog { get; set; }

    public DbSet<ProviderType> ProviderTypes { get; set; }
    public DbSet<ProviderSpecialty> ProviderSpecialties { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();

        modelBuilder.Entity<Provider>().HasRequired(cn => cn.Owner).WithMany().WillCascadeOnDelete(false);
        modelBuilder.Entity<Office>().HasRequired(cn => cn.Owner).WithMany().WillCascadeOnDelete(false);
    }
}

public class Provider
{
    public int Id { get; set; }

    public int OwnerId { get; set; }
    public virtual Owner Owner { get; set; }

    public int? ProviderTypeId { get; set; }
    public virtual ProviderType ProviderType { get; set; }

    public int? ProviderSpecialtyId { get; set; }
    public virtual ProviderSpecialty ProviderSpecialty { get; set; }

    [Required]
    [StringLength(75)]
    public string FirstName { get; set; }
    [StringLength(75)]
    public string MiddleName { get; set; }
    [Required]
    [StringLength(75)]
    public string LastName { get; set; }

    [StringLength(100)]
    public string EmailAddress { get; set; }

    public virtual ICollection<ProviderPhoneNumber> PhoneNumbers { get; set; }

    public string Note { get; set; }

    public DateTime? InactiveOn { get; set; }

    public int OfficeId { get; set; }
    public virtual Office Office { get; set; }

    public virtual ICollection<ProviderAuditLog> AuditLog { get; set; }

    [Required]
    public DateTime CreatedOn { get; set; }
    [Required]
    [StringLength(75)]
    public string CreatedBy { get; set; }
    [Required]
    public DateTime ModifiedOn { get; set; }
    [Required]
    [StringLength(75)]
    public string ModifiedBy { get; set; }
}

感谢您的帮助!

我不确定这对性能有多大帮助,但在 using 语句之外声明您不想处理的变量应该可以修复您的处理异常。

   public IEnumerable<Models.Provider> Get(string owner)
     {

    IEnumerable<Models.Provider> dtoProviders;
    using (var db = new Data.ProviderDirectoryContext())
    {
        List<Data.Models.Provider> providers = db.Providers.Where(p => p.Owner.Name == owner).ToList();

        dtoProviders = Mapper.Map<List<Data.Models.Provider>, List<Models.Provider>>(providers);
    }


    return dtoProviders;
}

问题是 Models.Provider class 包含其他 class ,如 Models.OfficeModels.PhoneNumbers ,它们没有被查询急切加载。除此之外,Models.Provider class 需要展平。 Mapper想递归映射所有东西,一直往下到下一个class。例如,Provider.Office.Location.Offices.

解决方案是展平 Models.Provider 并将 .Include() 添加到查询中,以便它快速加载所需的数据。

我会进一步清理它,但它目前正在运行。

public IEnumerable<Models.Provider> Get(string owner)
{
    List<Data.Models.Provider> providers;
    using (var db = new Data.ProviderDirectoryContext())
    {
        providers = db.Providers
            .Where(p => p.Owner.Name == owner)
            .Include("ProviderType")
            .Include("ProviderSpecialty")
            .Include("Office")
            .Include("PhoneNumbers")
            .ToList();
    }
    var dtoProviders = Mapper.Map<List<Data.Models.Provider>, List<Models.Provider>>(providers);
    return dtoProviders;
    }

public class Provider
{
    public int Id { get; set; }

    public int OwnerId { get; set; }

    public int OfficeId { get; set; }
    public string OfficeName { get; set; }

    public int? ProviderTypeId { get; set; }
    public string ProviderTypeName { get; set; }

    public int? ProviderSpecialtyId { get; set; }
    public string ProviderSpecialtyName { get; set; }

    public string FirstName { get; set; }
    public string MiddleName { get; set; }
    public string LastName { get; set; }

    public string EmailAddress { get; set; }

    public virtual ICollection<PhoneNumber> PhoneNumbers { get; set; }

    public string Note { get; set; }

    public DateTime? InactiveOn { get; set; }

    public DateTime CreatedOn { get; set; }
    public string CreatedBy { get; set; }
    public DateTime ModifiedOn { get; set; }
    public string ModifiedBy { get; set; }
}