2014-12-07 3 views
0

У меня есть 2 объекта, Пользователь и материал. Пользователь хранит сборник материалов.Обновление свойства навигации работает, но объект не отображается в коллекции

public class User 
{ 
... 

private ICollection<Material> materials; 

     public virtual ICollection<Material> Materials 
     { 
      get { return materials ?? (materials = new List<Material>()); } 
      set { materials = value; } 
     } 
} 

И материал:

public class Material 
    { 
... 
     public int? UserId { get; set; } 
     public virtual User User { get; set; } 
... 
    } 

При входе пользователь выбирает материал, поручает этот пользователь Material.User и сохранить изменения. Прекрасно работает, изменения сохраняются в db. Но, если я хочу получить доступ к материалам с User.Materials, коллекция не содержит элементов. Я пробовал с простым проектом и там он работает. С моим сложным проектом это не так. Что делать?

Помогите мне, пожалуйста, беспокоиться о проблемах в течение 8 часов и по-прежнему не использовать его.

EDIT: Ну, это так ... ламе.

Мой код фактически работал, но проблема была в том, что при просмотре сведений о пользователе я получил пользователя из базы данных и создал КОПИЮ с помощью cunstrictor. Я что-то упустил:

public User(User otherUser) 
     { 
      Id = otherUser.Id; 
      FirstName = otherUser.FirstName; 
      LastName = otherUser.LastName; 
      Shift = otherUser.Shift; 
      PassCode = otherUser.PassCode; 
      Type = otherUser.Type; 

      Materials = otherUser.Materials; // this line was missing 
     } 

После того, как эта линия добавлена, она работает. Просто Visual Studio жалуется на это (вызов виртуального участника в конструкторе). Что с этим делать?

+0

Вы удалили слишком много кода. В вашей проблеме нет ничего. – t3chb0t

+0

Больше ничего не показывать. Когда я выбираю материал, я называю метод, установить свойство пользовательского материала для текущего пользователя, например, так: 'общественная пустота SetBoxAsUnused (Материал материала, пользователь Пользователь) { material.User = пользователь context.SaveChanges (); } ' – Orochi

+0

« Виртуальный вызов участника в конструкторе »- это просто предупреждение. Если «Материалы» переопределены в подклассе (например, прокси!), Вы можете получить [неожиданные результаты] (http://stackoverflow.com/a/119543/861716). Решение состоит в том, чтобы присваивать 'otherUser.Materials'' материалам' (переменную-члену, которая, кстати, может быть названа '_materials' в соответствии с общими соглашениями об именах). –

ответ

0

Ваша проблема здесь:

private ICollection<Material> materials; 

    public virtual ICollection<Material> Materials 
    { 
     get { return materials ?? (materials = new List<Material>()); } 
     set { materials = value; } 
    } 

Entity Framework навигации свойство не может быть собственностью с полем подложки. Это может быть только автопромышленность. Поэтому вы должны использовать этот код:

public class User 
{ 
... 

     public virtual ICollection<Material> Materials 
     { 
      get; 
      set; 
     } 
} 
+0

Я получаю такой же результат с помощью autoproperty. – Orochi

+0

Вы использовали ленивую загрузку? Открывается ли dbcontext при попытке просмотреть свойство навигации? Покажите нам код, когда вы получите данные из базы данных и кода, когда вы получите null в свойстве навигации. –

+0

Я использую ленивую загрузку. Он работает для каждого отношения 1: M в моем проекте, проблемы exitsts только между этими двумя, где я позже устанавливаю свойство навигации. В любом случае, чтобы восстановить пользователя: 'return context.Users.Find (id);' Работает просто отлично, просто коллекция пуста. Здесь я получаю пустое исключение: '//MessageBox.Show(User.Materials.Count.ToString());'˙ Кроме того, я привязал эту коллекцию к списку, но не имеет отношения к концу. – Orochi

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