获取只读数据绑定使用EF POCO对象 [英] Getting Readonly Databind using EF POCO Objects

查看:201
本文介绍了获取只读数据绑定使用EF POCO对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用EF4与WPF。我数据绑定到DataGrid中的主从式的。想想罗斯文的客户 - >订单 - >订单明细

I am using EF4 with WPF. I am databinding to the DataGrid in a Master-Detail style. Think of the Northwind Customers -> Orders -> OrderDetails.

我所发现的是,当我使用POCO对象,订单和订单明细网格是只读的。如果我恢复使用设计器生成实体它们变成可编辑的。

What I am finding is that when I use POCO objects, the Orders and OrderDetails grids are read-only. If I revert to using the designer generated entities they become editable.

绑定XAML看起来是这样的:

The binding XAML looks like this:

<Window.Resources>
    <CollectionViewSource x:Key="CustomersViewSource" d:DesignSource="{d:DesignInstance my:Customer, CreateList=True}" />
    <CollectionViewSource x:Key="CustomersOrdersViewSource" Source="{Binding Path=Orders, Source={StaticResource CustomersViewSource}}" />
</Window.Resources>
<Grid DataContext="{StaticResource CustomersViewSource}">

    <DataGrid ItemsSource="{Binding}" >
    <DataGrid ItemsSource="{Binding Source={StaticResource CustomersOrdersViewSource}}" >

(我已删除属性不相关的数据绑定的,当然。)

(I've removed attributes not relevant to databinding, of course.)

此外,还有上下文实例绑定的标准形式加载事件:

Then there's the standard form load event to bind the context instance:

Dim NorthwindEntities As BindTest.NorthwindEntities = New BindTest.NorthwindEntities()
Dim CustomersViewSource As System.Windows.Data.CollectionViewSource = CType(Me.FindResource("CustomersViewSource"), System.Windows.Data.CollectionViewSource)
CustomersViewSource.Source = NorthwindEntities.Customers

在网格填充,但第二个是只读的,如果我用我的POCO的对象,如果编辑他们是标准的EF生成的对象。

The grids populate, but the second is readonly if I'm using my POCO objects, editable if they are the standard EF generated objects.

的关键似乎是在各实体的导航属性。我POCO对象是:

The key seems to be in the navigation properties of the entities. My POCO objects use:

Public Overridable Property Orders() As ICollection(Of Order)
    Get
        If _Orders Is Nothing Then  _Orders = New HashSet(Of Order)
   Return _Orders
    End Get
    Set(ByVal value As ICollection(Of Order))
        _Orders = value
    End Set
End Property

鉴于EF对象复杂得多:

Whereas the EF objects are much more complicated:

<XmlIgnoreAttribute()>
<SoapIgnoreAttribute()>
<DataMemberAttribute()>
<EdmRelationshipNavigationPropertyAttribute("NorthwindModel", "FK_Order_Details_Orders", "Orders")>
Public Property Order() As Order
    Get
        Return CType(Me, IEntityWithRelationships).RelationshipManager.GetRelatedReference(Of Order)("NorthwindModel.FK_Order_Details_Orders", "Orders").Value
    End Get
    Set
        CType(Me, IEntityWithRelationships).RelationshipManager.GetRelatedReference(Of Order)("NorthwindModel.FK_Order_Details_Orders", "Orders").Value = value
    End Set
End Property

有关缺少一些更好的措辞,似乎有在任的EntityCollection类型的属性一些魔法。 ICollection的是不是一个只读接口和一个HashSet的是不是只读无论是。

For the lack of some better wording, there seems to be some magic in either the attributes for the EntityCollection type. ICollection isn't a readonly interface and a HashSet isn't readonly either.

有关如何获取POCO在这里工作还是我坚持EF派生的对象,任何想法? (使单元测试困难。)

Any ideas about how to get POCO to work here or am I stuck with EF derived objects? (Makes unit testing difficult.)

感谢。

推荐答案

这个问题可能是,订单订单明细藏品类型的的ICollection&LT; T&GT; / 的HashSet&LT; T&GT; 在你的POCO例子。该数据网格WPF内部不与直接收藏,而是与工作相关的集合视图。当你收集绑定到DataGrid中的WPF绑定引擎将基于集合类型这个内部collection视图。

The problem is likely that the Orders and OrderDetails collections are of type ICollection<T> / HashSet<T> in your POCO example. The WPF datagrid internally does not work with the collection directly but rather with an associated "collection view". When you bind the collection to the DataGrid the WPF binding engine creates this internal collection view based on the type of the collection.

如果您的收藏仅仅实现了的IEnumerable 或只的ICollection 创建集合视图的类型为的CollectionView ,一类做的不可以实施 IEditableCollectionView 。这就是为什么当你HashSet的绑定到它,你不能编辑DataGrid中的原因。

If your collection implements only IEnumerable or only ICollection the type of the created collection view is CollectionView, a class which does not implement IEditableCollectionView. That's the reason why you can't edit the DataGrid when you bind a HashSet to it.

数据网格需要一个集合视图,它实现 IEditableCollectionView 允许编辑。这是例如的ListCollectionView (也是从的CollectionView 派生)。 WPF如果您的源集合实现的IList 接口创建该类型集合看法。

The DataGrid needs a collection view which implements IEditableCollectionView to allow editing. This is for example the ListCollectionView (which also derives from CollectionView). WPF creates this type of collection view if your source collection implements the IList interface.

所以,要解决你应该修改订单您POCO的属性的类型为 IList的问题

So, to fix the problem you should change the type of the Orders property of your POCO to IList:

Public Overridable Property Orders() As IList(Of Order)
    Get
        If _Orders Is Nothing Then  _Orders = New List(Of Order)
        Return _Orders
    End Get
    Set(ByVal value As IList(Of Order))
        _Orders = value
    End Set
End Property

修改

据@Allon Guralnek的评论下面,有必要实施非通用 的IList 接口获取一个可编辑的DataGrid。这是列表(共T)的情况下,因此上面的code仍然可以工作。只有实现在通用 的IList(Of T)已,但不是非通用的IList 不会使DataGrid的编辑。

According to @Allon Guralnek's comment below it is necessary to implement the non-generic IList interface to get an editable DataGrid. This is the case for List(Of T), therefore the code above will still work. Other implementations which only implement the generic IList(Of T) but not the non-generic IList won't make the DataGrid editable.

这篇关于获取只读数据绑定使用EF POCO对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆