Связывание EF4 с Caliburn.Micro. Должен ли я раскрывать свой Entity как свойство ViewModel?

Что касается Caliburn.Micro, я хотел бы узнать о плюсах и минусах представления объекта EF4 как свойства ViewModel (метод, обсуждаемый здесь и здесь ). Это позволяет мне не писать геттеры и сеттеры для каждого поля (см. OneCustomer ниже). Недостатком является то, что мне нужно написать все операторы привязки в XAML (ниже LastName не находится в ViewModel, но требует привязки XAML). Если я буду придерживаться предписанной техники заполнения моей ViewModel свойствами для каждого поля (как FirstName ниже), мне в конечном итоге придется написать тонну дополнительного кода только для того, чтобы вызывался NotifyOfProperyChange. Приложение будет довольно большим. Должен ли я предоставлять каждый объект как свойство ViewModel?

В моей модели представления:

private MyEntities _context = new MyEntities();
private BindableCollection<Customer> _custBindableCollection; 
private Customer _oneCustomer;
private string _firstName;

public void Load() 
{
    _custBindableCollection = new BindableCollection<Customer>(_context.Customers.Where(row => row.CustomerType == "FOO"));
    AllCustomers = _custBindableCollection;
    _oneCustomer = _custBindableCollection.FirstOrDefault();
    FirstName = _oneCustomer.FirstName;
    OneCustomer = _oneCustomer;
}

public BindableCollection<Customer> AllCustomers
{ 
get { return _custBindableCollection;}
set {_custBindableCollection = value;
      NotifyOfPropertyChange(() => AllCustomers);}
}

public Customer OneCustomer
{
 get { return _oneCustomer;}
 set { _oneCustomer = value;
        NotifyOfPropertyChange(() => OneCustomer);}
} 

public string FirstName
{
    get { return _firstName; }
    set {
        _firstName = value;
        _oneCustomer.FirstName = value;
        NotifyOfPropertyChange(() => FirstName);
        NotifyOfPropertyChange(() => CanSaveChanges);
    }
}

public void SaveChanges()
{ _context.SaveChanges(); }

public bool CanSaveChanges { get { return IsValid; } }

На мой взгляд:

<StackPanel>
<StackPanel Orientation="Horizontal">
    <Label Content="First Name:" />
    <TextBox x:Name="FirstName" />
</StackPanel>
<StackPanel Orientation="Horizontal" DataContext="{Binding Path=OneCustomer}">
    <Label Content="Last Name:" />
    <TextBox x:Name="LastName" Text="{Binding LastName}" />
</StackPanel>
<Button Content="Load Data" x:Name="Load" />
<Button Content="Save" x:Name="SaveChanges"  />
<DataGrid x:Name="AllCustomers" />

Thanks in advance.


person DeveloperDan    schedule 14.09.2011    source источник


Ответы (2)


С Caliburn.Micro я хотел бы знать плюсы и минусы предоставления объекта EF4 как свойства ViewModel (метод, обсуждаемый здесь и здесь).

Я не уверен в плюсах и минусах, но могу сказать, что используются оба метода. Например, возьмите простой экран входа в систему, обычно я помещаю имя пользователя в свойство ViewModel, но в случаях, когда форма более сложная, ViewModel может объединять другие ViewModels (модели отображения) для выполнения того же самого. CM не сильно влияет на плюсы и минусы, а скорее вопрос о плюсах и минусах MVVM. CM поможет вам в привязке к обоим.

  • Если у вас есть свойство ViewModel с именем CustomerName, просто назовите TextBox x:name="CustomerName".
  • Если у вас есть свойство в ViewModel, которое является экземпляром класса с именем Customer, назовите TextBox x:name="Customer_Name" и снова CM будет обрабатывать привязки.

Итак, из вашего xaml выше:

 <TextBox x:Name="LastName" Text="{Binding LastName}" />

вам не нужно устанавливать DataContext на StackPanel. Вместо:

<TextBox x:Name="OneCustomer_LastName"/>

Одна вещь, которая может упростить привязку к DataForms и DataGrids, — это следовать методу, в котором вы создаете модели отображения для того, как данные представлены на экране.

Это мое мнение, но лично я никогда не буду связываться напрямую с сущностью EF/Linq. Вместо этого я создам модель отображения для представления этой сущности и того, как я хочу ее отображать, и использую AutoMapper для сопоставления. Во многих случаях это сопоставление один к одному. Это может показаться пустой тратой времени, но у этого есть преимущества, особенно с более сложными макетами моделей данных, модели отображения позволяют сглаживать данные для целей отображения и атрибутировать свойства для проверки, не прикрепляя их к объекту модели данных. Подробнее об этом читайте в главе об этом в книге ASP.NET MVC в действии.

person Derek Beattie    schedule 15.09.2011
comment
Это отличная информация. Особенно соглашение CM об интерпретации подчеркивания как записи через точку. Я обязательно проверю AutoMapper и книгу MVC. Один небольшой вопрос, однако... должны ли быть обновлены свойства сущности в установщиках (до значения), или я должен подождать, пока не будет нажата кнопка сохранения, и обновить все сразу? Еще раз спасибо. - person DeveloperDan; 15.09.2011
comment
Вы спрашиваете, когда сохраняться в базе данных, когда значение свойства изменяется по сравнению с пользователем, нажимающим кнопку «Сохранить»? - person Derek Beattie; 16.09.2011
comment
Нет, я буду настаивать на сохранении (правило короткого, а не болтливого). Я думал, что если я не выставлю объект, я могу подождать, пока Сохранить не обновит все свойства объекта. Но теперь, когда я думаю об этом, это не имеет смысла, потому что мне пришлось бы обновлять все значения, даже если было изменено только одно. Итак, я ответил на свой вопрос - я буду хранить обновления свойств/полей объектов в установщиках. - person DeveloperDan; 17.09.2011
comment
@DerekBeattie ... Я знаю, что это старый вопрос, но я тоже изучаю его сейчас, и у меня есть вопрос относительно вашего предложения использовать модели отображения, а затем использовать AutoMapper для сопоставления ваших сущностей EF с моделями отображения. Я бы подумал, что, используя этот подход, вы потеряете преимущество двусторонней привязки данных между представлением, скажем, свойством TextBox.Text и свойством модели. Если пользователь вводит текстовое поле, я хочу, чтобы данные автоматически обновлялись в модели. Не будет ли Automapper мешать? - person Sean; 02.12.2014
comment
Через вызов ajax или что-то в этом роде? Этот ответ, вероятно, немного устарел. - person Derek Beattie; 03.12.2014

Поскольку есть и другие преимущества раскрытия сущностей (например, проверка с помощью атрибутов), лично я раскрываю их напрямую.

Но я думаю, что правильным ответом будет «это зависит», поскольку всегда есть и некоторые недостатки (в основном архитектурные).

Кстати: вы можете вызвать текстовое поле «OneCustomer_LastName», и привязка соглашения C.M будет работать.

person gius    schedule 15.09.2011