2013-12-22 2 views
0

Детское свойство ManagingAgent на сложной сущности не загружается данными ... возможно, результатом слишком большого количества глинтвейна.Entity Framework 6 - данные дочернего объекта не загружаются

Я записал SQL на вызовы базы данных, и SQL возвращает правильные данные.

LazyLoading отключен.

public ApplicationDbContext() 
     : base("DefaultConnection") 
{ 
    this.Configuration.LazyLoadingEnabled = false; 
} 

Совокупный Root

public class Complex 
{ 
    public Complex() 
    { 
     Forums = new List<Forum>(); 
     ManagingAgent = new ManagingAgent(); 
    } 

    [Key] 
    public int ComplexId { get; set; } 
    [Required] 
    public string Name { get; set; } 
    public string Address1 { get; set; } 
    public string Address2 { get; set; } 
    public string Address3 { get; set; } 
    public int? PostCodeId { get; set; } 
    public PostCode PostCode { get; set; } 
    public int? LocationId { get; set; } 
    public Location Location { get; set; } 
    public int? CountyId { get; set; } 
    public County County { get; set; } 
    public int? ManagingAgentId { get; set; } 
    public ManagingAgent ManagingAgent { get; set; } 
    public int? CountOfUnits { get; set; } 
    public List<Forum> Forums { get; set; }  
} 

Попытка 1. Включить используя ...

public List<Complex> GetComplexesByUserId(Guid userId) 
{ 
    using (var db = new ApplicationDbContext()) 
    { 
     db.Database.Log = Logger; 
     var complexIds = db.UserApartments.Where(r => r.UserId == userId) 
              .Select(c => c.ComplexId).ToList(); 
     return db.Complexes.Where(c => complexIds.Contains(c.ComplexId)) 
          .Include(m => m.ManagingAgent).ToList(); 
    } 
} 

Попытка 2 - явной загрузки ..same результат (SQL возвращает данные правильно, но ManagingAgent не является

public List<Complex> GetComplexesByUserId(Guid userId) 
{ 
    using (var db = new ApplicationDbContext()) 
    { 
     db.Database.Log = Logger; 
     var complexIds = db.UserApartments.Where(r => r.UserId == userId) 
              .Select(c => c.ComplexId).ToList(); 

     var list = new List<Complex>(); 

     foreach (var id in complexIds) 
     { 
      var complex = db.Complexes.Find(id); 
      db.Entry(complex).Reference(m => m.ManagingAgent).Load(); 
      list.Add(complex); 
     } 

     return list;     
    } 
} 

Таким образом, чтобы заставить груз я делаю это .... не хорошо ..

foreach (var id in complexIds) 
{ 
    var complex = db.Complexes.Find(id); 
    var managingAgent = db.ManagingAgents.Find(complex.ManagingAgentId); 
    complex.ManagingAgent = managingAgent; 
    list.Add(complex); 
} 
+0

Я не знал, что вы можете использовать 'Include' после вызова' Where', но если он поддерживается в EF6, тогда хорошо, но, возможно, вы можете попробовать заменить два -> 'return db.Complexes.Include (m => m.ManagingAgent) .Where (c => complexIds.Contains (c.ComplexId)). ToList(); ' – Silvermind

+1

У вас есть внешний ключ rel настройка ориентации в модели? Я не вижу, чтобы он определялся где-либо в приведенной выше настройке, и это объясняет согласованность обеих версий, не загружающих дочерний объект. Если нет отношений, он не знает, как/что загрузить. – Khepri

+0

@ Kepri - у вас может быть точка. Я проверил диаграмму схемы с помощью электроинструментов, и это выглядело отлично. Я только что проверил db, и что-то не выглядит правильным. У комплекса есть внешний ключ для ManagingAgent, но у ManagingAgent нет внешнего ключа для комплекса. Комплекс может иметь 0 или 1 ManagingAgent, но ManagingAgent может иметь 0 или много комплексов. Должна быть проблема с отношениями ... нужно попробовать несколько разных мощностей // – Greg

ответ

1

Удалить эту строку ...

ManagingAgent = new ManagingAgent(); 

... из конструктора Complex объекта. Тогда это сработает. (Вообще не инстанцируют ссылки навигационных свойств в конструкторе Субъекта по умолчанию. EF вызывает этот конструктор с помощью отражения, когда он материализует объект и «путается», если навигационное свойство уже есть ссылка. Я не могу объяснить «запутается» лучше, так как я не знаю точного механизма материализации объекта со связанными объектами, но эффект заключается в том, что значения загруженного дочернего столбца игнорируются, потому что уже создан экземпляр дочернего объекта, но только с бесполезными значениями по умолчанию из конструктора ManagingAgent.)

+0

Является ли это новым в EF6? Я спрашиваю, потому что если вы используете EF Power Tools для обратной инженерии существующей базы данных, она создаст заглушки для создания эталонных объектов в конструкторе, как в приведенном выше примере. – Khepri

+0

@ Khepri: Нет, это не ново. Вы уверены, что EF Power Tools? Он создает * пустые коллекции *, да, и это не проблема. Но я никогда не видел * ссылок * в автогенерированном коде. См. Например пример 'Product' /' Category' в конце этого сообщения: http://romiller.com/2012/05/09/customizing-reverse-engineer-code-first-in-the-ef-power -tools/'Product' не имеет конструктора, который создает экземпляр' Category', только 'Category' имеет конструктор с пустым списком' Product'. – Slauma

+0

Ах, ты прав. Виноват. Я взглянул на свои классы авто-gen'd, и у меня был небольшой мозговой кризис. Благодарю. – Khepri

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