2012-11-15 109 views
1

我在數據綁定和實體框架的導航屬性方面遇到了一些麻煩。與實體框架的數據綁定使用組合框的導航屬性

我有兩個班,由實體框架設計器生成的:

類Foo

id (int) 
bar (Bar) 
... 

類酒吧

id (int) 
name (string) 
... 

使用的ObservableCollection<Foo>,我已填充一個包含以下列的數據網格:

<DataGrid.Columns> 
    <DataGridTextColumn Header="Id" Binding="{Binding Path=id}"/> 
    <DataGridTemplateColumn Header="Bar"> 
     <DataGridTemplateColumn.CellTemplate> 
      <DataTemplate> 
       <ComboBox 
        SelectedValuePath="Id" 
        SelectedValue= 
         "{Binding Path=bar.Id, Mode=TwoWay, 
         UpdateSourceTrigger=PropertyChanged}" 
        DisplayMemberPath="name" 
        ItemsSource= 
         "{Binding Path=BarList, 
         RelativeSource={RelativeSource FindAncestor, 
         AncestorType={x:Type Window}}}" 
        Background="White" /> 
      </DataTemplate> 
     </DataGridTemplateColumn.CellTemplate> 
    </DataGridTemplateColumn> 
</DataGrid.Columns> 

組合框被填入一個ObservableCollection<Bar>並且正確地顯示當前Bar

當我在組合框中選擇另一個項目時出現問題。我收到以下錯誤:

System.Windows.Data Error: 8 : Cannot save value from target back to source. 

System.InvalidOperationException: The property 'Id' is part of the object's key information and cannot be modified 

我可以看到彈出錯誤的原因,但我該如何處理這個問題?

編輯:FooBar之間的關係是N..1,這意味着一個Foo具有1或0 Bar而酒吧可以有幾個Foo

目前,我無法爲我的Foo s選擇新的Bar

+0

你好@thakrage!你到底想在這裏完成什麼?改變你的一個ViewModel的ID確實看起來有問題! – Sisyphe

+0

我沒有使用MVVM,但我想要一個包含酒吧列表的組合框。從這個列表中,我希望能夠爲我的Foo選擇另一個Bar。我將編輯問題 –

+0

即使您沒有使用MVVM,您的DataGrid似乎也是綁定的。所以你的每一行都是從一個底層對象生成的(在你的情況下是一個Foo)你是否想在ComboBox中選擇一個值時修改ObservableCollection ?編輯:剛剛看到你的編輯:所以comboxBox是爲了讓用戶選擇一個酒吧給予FOO? – Sisyphe

回答

2

您必須直接綁定bar屬性。您的代碼嘗試更改所選Foo的欄上的Id,但您想要更改與當前Foo關聯的欄。您還必須覆蓋Bar課程中的Equals方法。

<ComboBox SelectedValue="{Binding bar, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
      DisplayMemberPath="Name" 
      ItemsSource="{Binding Path=BarList, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" Background="White" /> 

而在你Bar類:

public override bool Equals(object obj) 
{ 
    if (obj is Bar) 
     return ((Bar)obj).Id == Id; 
    return false; 
} 
0

對我來說,它看起來像這個問題更與實體框架比WPF。 bar的id是否同時是foo的主鍵的一部分,這是否正確?至少綁定,ComboBox的設置和錯誤消息似乎暗示了這一點。

實體框架的侷限性之一是它不支持關鍵更新。如果要更改對象的鍵,則基本上必須刪除它,使用新鍵重新創建它,並複製所有其他屬性。在我目前正在研究的一個程序中,我決定創建一個包裝類,它將Id作爲屬性公開,並在更改後在幕後處理。我已經看過帖子,建議只分離對象並重用它,但在我的情況下,這沒有奏效。

+0

那麼Entity-Framework沒有問題,問題確實與WPF有關。如果您閱讀我們的評論,thakrage聲明他想更改與Foo相關的條形圖,他的綁定會嘗試更改條形圖的ID(由於更新限制,這似乎確實不正確)。這是一個簡單的綁定錯誤。 – Sisyphe

+0

再次想到我認爲你是對的。我可能被錯誤信息誤導了。這完全取決於錯誤代碼的意圖。 – hbarck

2

如果你不想使用它的對象直接(這意味着不使用SelectedValuePathSelectedValue而是使用SelectedItem="{Binding Foo.Bar}"直接,你需要在EF設計指導到generate foreign key property BarId on the Foo entity,那麼你就可以綁定SelectedValue="{Binding Foo.BarId}"做。