2015-02-20 2 views
1

При вызове метода непосредственно ниже я получаю ObjectDisposedException при вызове Mapper.Map с извлеченным списком.Получение ошибки ObjectContext даже после вызова ToList

System.ObjectDisposedException: экземпляр ObjectContext был удален и больше не может использоваться для операций, требующих подключения.

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

Спасибо за помощь!

+0

У вас есть какие-либо функции/свойства внутри 'Data.Models.Provider', которые обращаются к любым контекстным функциям? –

+0

Спасибо за ответ @StephenReindl. Я не думаю, что делаю что-то особенное в «Data.Models.Provider», но я добавил его в сообщение. – JuanitoCROM

ответ

1

Проблема заключается в том, что Models.Provider класс содержит другие классы, как Models.Office и Models.PhoneNumbers, которые не были охотно загружены по запросу. Кроме того, класс Models.Provider должен быть сплющен. Mapper хочет рекурсивно отобразить все, и он переходит к следующему классу. Например, 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; } 
} 
0

Я не уверен, насколько это поможет в производительности, но объявив переменную, которую вы не хотите использовать вне оператора 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; 
} 
+0

Спасибо @jackncoke. Хотя это помогает с исключением, производительность ужасна. Есть около 6000 провайдеров, и для картирования требуется 36 секунд. – JuanitoCROM

+0

Вам нужны все свойства, которыми вы занимаетесь? Можете ли вы создать более короткую версию этого класса только с тем, что вам нужно? Это должно уменьшить время отображения. – jackncoke

+0

Спасибо @jackncode, но я нашел проблему. Я отправлю ответ. – JuanitoCROM

Смежные вопросы