2014-01-25 2 views
1

В моем приложении MVC4, EF6 я создаю объект «Контакт». этот контакт содержит объект «Адрес». оба экземпляра создаются на одном и том же представлении. это, как я это сделать на стороне контроллера:EF6 потерянное отношение между enitites

enter image description here

я могу видеть, что это создает оба экземпляра просто прекрасно, когда я взглянуть на мой Дб. Вот как это выглядит:

Таблица адресов:

enter image description here

Контакты Стол:

enter image description here

Это все работает замечательно, пока я не перезагрузить приложение. это действие приводит к тому, что отношения между моим контактом и его адресом исчезают. Вот как это выглядит на моем втором прогоне: enter image description here

Вот мой адрес класса:

enter image description here

И мой Контакт Класс:

enter image description here

любая идея, почему это происходит? Спасибо.

+0

Можем ли мы видеть ваши классы 'Контакты' /' Address'/mapping? Похоже, что соответствующие свойства не лениво загружаются. Возможно, вам придется объявить свойство virtual или явно загрузить связанные объекты, в зависимости от того, как выглядят ваши классы. – Chris

+0

Конечно. взгляните на отредактированный вопрос. Спасибо. – user3087881

+0

виртуальное ключевое слово позволяет Entity Framework «откладывать» загрузку свойств навигации до тех пор, пока они не будут доступны. Свойства навигации обычно не возвращаются до тех пор, пока они не будут доступны. Вы находите, что свойства отсутствуют при доступе к ним или вы просто проверяете эту конкретную точку останова после первого запроса к базе данных? – Claies

ответ

0

Это потому, что вы создаете новый Address в своем конструкторе Contact.

Попробуйте вместо этого:

public Contact() 
{ 
     FirstName = String.Empty; 
     LastName = String.Empty; 
     //Address = new Address(); <-- remove this line 
} 

В качестве альтернативы, используйте Include к «Eager-Load» Address так что вы не должны полагаться на прокси-сервер для «Ленивый-Load» Address для вас.

Edit:

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

private Address _address; 

public virtual Address Address 
{ 
     get { return _address ?? (_address = new Address()); } 
     set { _address = value; } 
} 
+0

Можете ли вы объяснить «Включить» и что это такое? – user3087881

+0

Поскольку вы абстрагируете контекст платформы Entity Framework с использованием шаблона репозитория, я думаю, у вас нет прямого доступа к методу 'Include'. Тем не менее, в реализации метода ContactRepository.GetById (id) 'вы можете его вызвать. что-то вроде: 'return this.Contacts.Include (x => x.Address) .Single (x => x.Id == id);' – haim770

+0

Метод 'Include' предназначен для« связанных с загрузкой »данных, вместо «lazy-load», что означает, что контекст будет запрашивать базу данных для данных «Address» только при доступе к ее навигационному свойству. В терминах SQL это просто означает, что исходный оператор SQL уже будет содержать необходимое предложение 'JOIN' для таблицы« ContactAddress »(или того, что вы на самом деле назвали ее). – haim770

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