使用 ComboBox 的实体框架导航属性进行数据绑定



我在数据绑定和实体框架的导航属性方面遇到了一些问题。

我有两个类,由实体框架设计器生成:

福类

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选择新Bar

您必须直接绑定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;
}

如果您不想直接使用对象来执行此操作(这意味着不使用SelectedValuePathSelectedValue而是直接使用SelectedItem="{Binding Foo.Bar}",则需要指示 EF 设计器generate foreign key property BarId on the Foo entity,然后您可以绑定SelectedValue="{Binding Foo.BarId}"

对我来说,问题似乎更多地在于实体框架而不是WPF。bar的id同时是foo主键的一部分是正确的吗?至少绑定,组合框的设置和错误消息似乎暗示了这一点。

实体框架的限制之一是它不支持密钥更新。如果要更改对象的键,基本上必须删除它,使用新键重新创建它,然后复制所有其他属性。在我目前正在处理的一个程序中,我决定创建一个包装类,它将 Id 公开为属性,并在更改时在幕后执行此处理。我见过建议仅分离对象并重用它的帖子,但就我而言,这不起作用。

相关内容

  • 没有找到相关文章

最新更新