2011-09-14 22 views
5

Caliburn.Microでは、EF4エンティティをViewModelのプロパティ(公開されている技術hereand here)として公開することの長所と短所を知りたいと思います。これにより、すべてのフィールドにgetterとsetterを書くのを避けることができます(下記のOneCustomerを参照してください)。欠点は、すべてのバインディングステートメントをXAMLに書き込む必要があることです(LastNameはViewModelにはありませんが、XAMLバインディングが必要です)。私がViewModelに各フィールドのプロパティ(下のFirstNameとして)を埋め込むという所定のテクニックに固執すれば、私は最終的にNotifyOfProperyChangeが呼び出されるように1トンの余分なコードを書く必要があります。アプリケーションはかなり大きくなります。 各エンティティをViewModelのプロパティとして公開する必要がありますか?私の見解ではCaliburn.MicroでEF4をバインドする:自分のエンティティを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; } } 

:私のViewModelで

事前に

<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" /> 

感謝。

答えて

5

私はViewModelに(ここでは とここで説明技術)のプロパティとして EF4実体を暴露するの長所と短所を知っているように思います。

私は賛否両論は分かりませんが、両方の方法が使用されていると言えます。たとえば、簡単なログイン画面を使用する場合、一般にViewModelにUserNameプロパティを設定しますが、フォームが複雑な場合は、ViewModelが同じViewModel(ディスプレイモデル)を集約して同じことを達成できます。 CMは、MVVMを使用した場合のより多くの問題として、長所/短所に何か影響を与えません。 CMは両方にバインドするのを手助けするつもりです。

  • ViewModelにCustomerNameという名前のプロパティがある場合は、単に という名前のTextBox x:name = "CustomerName"とします。
  • Customerという名前のクラス のインスタンスであるViewModelのプロパティを持っている場合は、TextBox x:name = "Customer_Name"という名前を付け、CM がバインディングを処理します。

したがって、上記のあなたのXAMLから:

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

あなたはStackPanelの上のDataContextを設定する必要はありません。代わりに:簡単にデータフォームとデータグリッドへの結合を作ることができます

<TextBox x:Name="OneCustomer_LastName"/> 

ことの一つは、あなたがデータを画面上に表示されている方法のためのディスプレイモデルを作成する方法次のようです。

これは私の意見ですが、個人的にはEF/Linqエンティティに直接バインドすることはありません。代わりに、そのエンティティを表すための表示モデルを作成し、その表示方法を入力して、AutoMapperを使用してマッピングを行います。多くの場合、それは1対1のマッピングです。これは時間の無駄だと思われるかもしれませんが、特に複雑なデータモデルのレイアウトではメリットがあります。表示モデルを使用すると、表示目的でデータを平坦化し、データモデルエンティティに貼り付けることなく検証のプロパティを属性付けできます。その詳細については、ASP.NET MVC in Action本の章を参照してください。

+0

これは素晴らしい情報です。特に、アンダースコアをドット表記と解釈するCMの慣行。私は間違いなくAutoMapperとMVCの本をチェックします。しかし、1つの小さな質問...セッターで(値に)エンティティプロパティを更新する必要がありますか、または保存をクリックして一度にすべてを更新するまで待つ必要がありますか?再度、感謝します。 – DeveloperDan

+0

プロパティの値が変更されたときと保存したときのどちらを比較してデータベースに保存するかを尋ねていますか? –

+0

いいえ、私は救いを続けるつもりです。私が考えていたことは、エンティティを公開しないと、すべてのエンティティプロパティを更新するために保存まで待つことができるということです。しかし、今は私が考えることは意味がありません。なぜなら、1つだけが変更されたとしてもすべての値を更新する必要があるからです。だから、私自身の質問に答えました - 私はセッターにエンティティのプロパティ/フィールドの更新を保持します。 – DeveloperDan

3

エンティティを公開することによる他の利点(属性による検証など)があるため、私は個人的に直接公開します。

しかし、私は適切な答えは、常にいくつかの欠点(主に建築)があるので「それは依存する」と思う。

BTW: "OneCustomer_LastName"というテキストボックスを呼び出すことができ、C.Mのコンベンションバインディングが機能します。 Caliburn.Microで

+0

私は2つの答えを受け入れることができたらいいと思います。ご協力いただきありがとうございます。 – DeveloperDan

関連する問題