将EF4与Caliburn.Micro绑定:我应该将我的实体作为ViewModel的属性公开吗?

时间:2011-09-14 21:00:10

标签: wpf entity-framework mvvm caliburn.micro

使用Caliburn.Micro我想知道将EF4实体暴露为ViewModel属性的优缺点(一种讨论的技术here and here)。这使我可以避免为每个字段编写getter和setter(参见下面的OneCustomer)。缺点是我需要在XAML中编写所有绑定语句(LastName不在ViewModel中,但需要XAML绑定)。如果我坚持使用每个字段的属性填充我的ViewModel的规定技术(如下面的FirstName),我最终必须编写大量的额外代码才能调用NotifyOfProperyChange。该应用程序将非常庞大。 我应该将每个实体公开为ViewModel的属性吗?

在我的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" />

提前致谢。

2 个答案:

答案 0 :(得分:5)

  

有了Caliburn.Micro,我想知道揭露一个人的利弊   EF4实体作为ViewModel的属性(这里讨论的技术   在这里)。

我不确定利弊,但我可以告诉你这两种方法都被使用了。例如,使用一个简单的登录屏幕,通常我将UserName放在ViewModel上,但是在表单更复杂的情况下,ViewModel可以聚合其他ViewModel(显示模型)来完成同样的事情。 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}" />

您不需要在StackPanel上设置DataContext。代替:

<TextBox x:Name="OneCustomer_LastName"/>

可以更容易地绑定到DataForms和DataGrids的一件事是遵循一种方法,在该方法中,您可以为屏幕上的数据表示方式创建显示模型。

这是我的观点,但我个人永远不会直接绑定到EF / Linq实体。相反,我将创建一个显示模型来表示该实体以及我希望它如何显示,并使用AutoMapper来进行映射。在很多情况下,它是一对一的映射。这似乎是浪费时间,但它具有优势,特别是对于更复杂的数据模型布局,显示模型允许您展平数据以用于显示目的,并将属性归因于验证而不将其粘贴在数据模型实体上。有关详情,请查看ASP.NET MVC in Action书中的相关章节。

答案 1 :(得分:3)

由于暴露实体还有其他优点(例如,通过属性验证),我个人会直接公开它们。

但我认为正确的答案是“它取决于”,因为总有一些缺点(主要是建筑)。

BTW:您可以调用文本框“OneCustomer_LastName”,并且C.M的约定绑定将起作用。