将对象绑定到控件(实体框架)
通过对象服务,您可以将控件(如 ComboBox、ListView 和 DataGridView 控件)绑定到 EntityCollection 或执行 ObjectQuery 时所返回的 ObjectResult。这两个实体框架类都实现用于数据绑定的 IListSource 接口。所有实体对象都派生自 StructuralObject 基类,该基类实现 INotifyPropertyChanged。这样便可在对象属性和控件之间实现双向数据绑定,从而将对控件的更新传播回绑定对象的属性。
若要将对象绑定到 Windows 窗体控件,请将该控件的 DataSource 属性设置为 EntityCollection 或对 ObjectQuery 对象调用 Execute 方法时所返回的 ObjectResult。下面的示例将 EntityCollection 绑定到 DataGridView 控件:
' Bind the items for this order to the DataGridView.
lineItemsDataGrid.DataSource = order.SalesOrderDetail
// Bind the items for this order to the DataGridView.
lineItemsDataGrid.DataSource = order.SalesOrderDetail;
有关更多信息,请参见如何:将对象绑定到 Windows 窗体控件(实体框架)。
可以创建基于 Visual Studio 应用程序中的对象的数据源。在将实体类型定义为项目中的数据源后,通过将**“数据源”**窗口中的项拖到窗体上即可创建显示实体数据模型 (EDM) 数据的窗体。这些项将成为窗体上绑定到该数据源的控件。有关更多信息,请参见“数据源”窗口。在运行时,您将类型化 ObjectQuery 的结果分配给该数据源所使用的 BindingSource 的 DataSource 属性。这会显示由这些控件中的查询所返回的对象的属性。与直接数据绑定一样,在调用 SaveChanges 方法时会将对控件值所做的更新应用于该数据源。有关更多信息,请参见如何:添加对象作为项目数据源(实体框架)。
若要将对象绑定到 Windows Presentation Foundation (WPF) 控件,请将该控件的 DataContext 属性设置为 EntityCollection 或对 ObjectQuery 对象调用 Execute 方法时所返回的 ObjectResult。使用 ItemsSource 属性设置该控件的对象源。若要将控件绑定到导航属性所返回的相关对象,请在为 ItemsSource 属性定义的绑定中包含相应的路径。该路径相对于父控件的 DataContext 属性所设置的根对象。下面的示例设置 Grid 控件的 DataContext 属性以将该控件绑定到 ObjectResult:
' Execute the query and bind the result to the OrderItems control.
Me.orderItemsGrid.DataContext = query.Execute(MergeOption.AppendOnly)
// Execute the query and bind the result to the OrderItems control.
this.orderItemsGrid.DataContext = query.Execute(MergeOption.AppendOnly);
下面的示例显示 ListView 和 ComboBox 子控件的 XAML 绑定定义:
<ComboBox DisplayMemberPath="SalesOrderID" ItemsSource="{Binding}"
IsSynchronizedWithCurrentItem="true"
Height="23" Margin="122,12,198,0" Name="comboBoxOrder" VerticalAlignment="Top"/>
<ListView ItemsSource="{Binding Path=SalesOrderDetail}" Name="listViewItems" Margin="34,46,34,50">
<ListView.View>
<GridView AllowsColumnReorder="False" ColumnHeaderToolTip="Line Items">
<GridViewColumn DisplayMemberBinding="{Binding Path=ProductID}"
Header="Product" Width="50"/>
<GridViewColumn DisplayMemberBinding="{Binding Path=OrderQty}"
Header="Quantity" Width="50"/>
<GridViewColumn DisplayMemberBinding="{Binding Path=UnitPrice}"
Header="Cost" Width="50"/>
<GridViewColumn DisplayMemberBinding="{Binding Path=LineTotal}"
Header="Line Total" Width="80"/>
</GridView>
</ListView.View>
</ListView>
有关更多信息,请参见如何:将对象绑定到 Windows Presentation Foundation 控件(实体框架)。
实体框架包含 EntityDataSource Web 服务器控件。可以使用此 ASP.NET 数据源控件将对象查询的结果绑定到 ASP.NET 网页上的控件。有关更多信息,请参见 EntityDataSource 控件示例。
在将对象绑定到控件时需要考虑下列注意事项:
我们建议您不要将控件直接绑定到 ObjectQuery,而应将控件绑定到 Execute 方法的结果。用此方式进行绑定可防止在绑定期间多次执行查询。
下面的示例将 ComboBox 绑定到执行类型为 SalesOrderHeader 的 ObjectQuery 时所返回的 ObjectResult。
' Create a query for orders that includes line items. Dim orderQuery As ObjectQuery(Of SalesOrderHeader) = _ context.SalesOrderHeader _ .Where("it.CustomerID = @customerId", _ New ObjectParameter("customerId", customerId)) _ .Include("SalesOrderDetail") ' Bind the combo box to the ObjectResult of SalesOrderHeader ' that is returned when the query is executed. Me.ordersListBox.DataSource = orderQuery.Execute(MergeOption.AppendOnly)
// Create a query for orders that includes line items. ObjectQuery<SalesOrderHeader> orderQuery = context.SalesOrderHeader .Where("it.CustomerID = @customerId", new ObjectParameter("customerId", customerId)) .Include("SalesOrderDetail"); // Bind the combo box to the ObjectResult of SalesOrderHeader // that is returned when the query is executed. this.ordersListBox.DataSource = orderQuery.Execute(MergeOption.AppendOnly);
为确保数据源是最新的,可能需要使用 Execute 方法再次执行查询。这会将控件绑定到新的 ObjectResult。在下列情况下,应执行此操作以确保对象数据是最新的:
对绑定控件外部的同一 ObjectContext 进行更改。
对数据源中的数据进行更改。
使用 NoTracking 选项返回了对象。
执行数据绑定后,可以从控件访问各实体对象。但不能从绑定控件访问集合。有关更多信息,请参见如何:将对象绑定到 Windows 窗体控件(实体框架)。
由于 EntityCollection 实现 IListSource,因此可将其绑定到控件。但对 EntityCollection 执行 OfType 方法以返回派生类型的对象集合时,不能直接将返回的 IEnumerable 绑定到控件。若要将控件绑定到从 EntityCollection 获取的派生类型的对象集合,请改用 CreateSourceQuery 方法获取定义基 EntityCollection 的 ObjectQuery。可以将控件绑定到 ObjectQuery 上的 OfType 方法所返回的 ObjectQuery 的执行。