Лучший отвечающий
EntityFramework и Combobox.SelectedItem

Вопрос
-
В базе данных есть таблицы: Employees и Appointments (сотрудники и должности).
В Employees есть поле Appointment [int32], которое ссылается на Appointments.id
Для БД автоматически создана EntityModel "Geocomplex.edmx"
Необходимо сделать редактирование и просмотр данных работника.
Данные получаются из базы стандартно:
public EmployeesWindow() { InitializeComponent(); GeocomplexEntities context = new GeocomplexEntities(); lbxEmployees.ItemsSource = context.Employees.ToList(); }
Отображаются, насколько я понимаю тоже стандартно.
Привязываем DataContext к текущему выбранному сотруднику:
<Grid DataContext="{Binding ElementName=lbxEmployees, Path=SelectedItem}">
Выводим информацию о нем в элементы управления:<TextBlock Text="{Binding Path=Appointment.Name}" Grid.Column="1" d:DataContext="{d:DesignInstance CompanyDb:Employee}" Grid.Row="1" /> <ComboBox ItemsSource="{Binding Source={StaticResource Appointments}}" SelectedItem="{Binding Appointment}" Grid.Column="1" d:DataContext="{d:DesignInstance CompanyDb:Employee}" Grid.Row="2"> <ComboBox.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding Path=Name}"/> </DataTemplate> </ComboBox.ItemTemplate> </ComboBox>
, где StaticResource Appointments это ObjectDataProvider
<ObjectDataProvider
x:Key="Appointments"
ObjectType="{x:Type CompanyDb:Catalog}"
MethodName="GetAppointments"> </ObjectDataProvider>
Класс Catalog, созданный для ObjectDataProvider:
public class Catalog { public List<Appointment> Appointments { get; set; } public Catalog() { GeocomplexEntities context = new GeocomplexEntities(); Appointments = context.Appointments.ToList(); } public List<Appointment> GetAppointments() { return Appointments; } }
Вроде бы все правильно, но при открытии в ComboBox не показывается должность (пустое поле). Однако, при изменении его, одновременно изменяется и TextBlock.
Почему-то одинаковые Appointment, полученные в разное время при сравнении получаются разными. Я попробовал переопределить метод Equals автоматически генерируемого класса Appointment, возвращая true при одинаковом Id, все заработало.
Однако, когда я поменял что-то в базе данных и сделал "Update model from database", мои изменения были удалены и классы сгенерированы заново.
Подскажите, в чем причина "неодинаковости" и как мне решить задачу? Только начинаю разбираться в EntityFramework по примерам, возможно все делаю не так
10 июня 2013 г. 13:33
Ответы
-
"Одинаковые" они в вашем понимании, т.к. имеют одинаковые Имена, названия, ID'шники и т.д. Программа же не знает по каким параметрам определять равенство сущностей и поэтому она сравнивает их по ссылкам, которые естественно у ваших объектов будут разными. Вы верно сделали, что переопределили Equals и GetHashCode только переопределите их в отдельном partial-классе для необходимой сущности. Таким образом вы избавитесь от переписывания логики сравнения при каждом вызове "Update model from database", правда придется проставить ключевое слово partial у сущностей.
- Предложено в качестве ответа ulcerModerator 11 июня 2013 г. 6:09
- Помечено в качестве ответа Валерий Осипов 11 июня 2013 г. 6:32
11 июня 2013 г. 3:25
Все ответы
-
"Одинаковые" они в вашем понимании, т.к. имеют одинаковые Имена, названия, ID'шники и т.д. Программа же не знает по каким параметрам определять равенство сущностей и поэтому она сравнивает их по ссылкам, которые естественно у ваших объектов будут разными. Вы верно сделали, что переопределили Equals и GetHashCode только переопределите их в отдельном partial-классе для необходимой сущности. Таким образом вы избавитесь от переписывания логики сравнения при каждом вызове "Update model from database", правда придется проставить ключевое слово partial у сущностей.
- Предложено в качестве ответа ulcerModerator 11 июня 2013 г. 6:09
- Помечено в качестве ответа Валерий Осипов 11 июня 2013 г. 6:32
11 июня 2013 г. 3:25 -
Чуть расширю. EF, по крайней мере в версии 5, генерирует все классы как Partial. Т.е. у вас есть файл с классом вида:
public partial class Appointment { ...
Добавляете в проект еще один класс (файл только назовите как нибудь Appointment.partial.cs). А у самого класса объявление сделайте как в исходном классе сгенерированном EF. Ну и переопределяйте те свойства, которые вам нужны.
Например, у нас для класса Person переопределен метод ToString:
public partial class Person { public override string ToString() { return String.Format("{0} {1} {2}", LastName, FirstName, Middlename); } }
11 июня 2013 г. 5:21Отвечающий