【发布时间】:2013-01-22 05:46:21
【问题描述】:
如何使用 Asp.net 动态数据从多个关系实体中创建表单。
例如我有一个与地址主关联的客户表。 (1 -> 0.1)
我想在创建和编辑客户时将这两个实体显示在一个页面上。
我如何通过动态数据脚手架实现这一点。
【问题讨论】:
标签: asp.net asp.net-dynamic-data
如何使用 Asp.net 动态数据从多个关系实体中创建表单。
例如我有一个与地址主关联的客户表。 (1 -> 0.1)
我想在创建和编辑客户时将这两个实体显示在一个页面上。
我如何通过动态数据脚手架实现这一点。
【问题讨论】:
标签: asp.net asp.net-dynamic-data
首先,您应该自定义 Insert.aspx 和 Edit.aspx 页面模板How to: Customize the Layout of an Individual Table By Using a Custom Page Template 以便在自定义页面上放置额外的(GridView 或 FormView)用于显示另一个实体的控件。
下一步如下。考虑编辑客户的例子。
~/DynamicData/CustomPages/Customer/Edit.aspx(部分):
<%-- FormView with Customer entity --%>
<asp:FormView
ID="FormViewEditCustomer"
runat="server"
DataSourceID="EditCustomerDataSource"
DefaultMode="Edit"
OnItemCommand="FormViewEditCustomer_ItemCommand"
OnItemDeleted="FormViewEditCustomer_ItemDeleted"
RenderOuterTable="false">
<EditItemTemplate>
<table id="editTable" class="table-edit" cellpadding="6">
<asp:DynamicEntity runat="server" Mode="Edit" />
</table>
</EditItemTemplate>
</asp:FormView>
<asp:EntityDataSource
ID="EditCustomerDataSource"
runat="server"
EnableUpdate="true"
EnableDelete="true"
OnUpdated="EditCustomerDataSource_Updated"
OnSelected="EditCustomerDataSource_Selected"/>
<asp:QueryExtender
ID="EditCustomerQueryExtender"
TargetControlID="EditCustomerDataSource"
runat="server">
<asp:DynamicRouteExpression />
</asp:QueryExtender>
GridView 带有 Address 实体 - 带有 QueryExtender 和 DynamicRouteExpression 的版本 1
<%-- GridView with Address entity - Version 1 with DynamicRouteExpression --%>
<asp:GridView
ID="GridViewAddress"
runat="server"
DataSourceID="AddressDataSource"
AllowPaging="true"
AllowSorting="false"
PageSize="10"
CssClass="table-list"
AutoGenerateColumns="true">
</asp:GridView>
<asp:EntityDataSource
ID="AddressDataSource"
runat="server"
ConnectionString="name=Entities"
DefaultContainerName="Entities"
EntitySetName="Address" />
<asp:QueryExtender
ID="AddressQueryExtender"
TargetControlID="AddressDataSource"
runat="server">
<asp:DynamicRouteExpression ColumnName="Customer_Id" />
</asp:QueryExtender>
在版本1中,我们使用了一种特殊类型的数据源表达式DynamicRouteExpression。在运行时,此对象从 URL 中提取主键列的值,并修改 AddressDataSource 生成的查询以包含适当的过滤条件。
需要注意的是表(实体)Address必须包含列名Customer_Id(和NOT例如Address_Customer_Id),否则 GridViewAddress 将包括所有地址。
GridView 带有 Address 实体 - 带有带有 CustomExpression 和 OnQuerying 的 QueryExtender 的版本 2 是更强大的版本
<%-- GridView with Address entity - Version 2 with QueryExtender with CustomExpression and OnQuerying --%>
<asp:GridView
ID="GridViewAddress"
runat="server"
DataSourceID="AddressDataSource"
AllowPaging="true"
AllowSorting="false"
PageSize="10"
CssClass="table-list"
AutoGenerateColumns="true">
</asp:GridView>
<asp:EntityDataSource
ID="AddressDataSource"
runat="server"
ConnectionString="name=Entities"
DefaultContainerName="Entities"
EntitySetName="Address" />
<asp:QueryExtender
ID="AddressQueryExtender"
TargetControlID="AddressDataSource"
runat="server">
<asp:CustomExpression
OnQuerying="AddressQueryExtender_Querying" />
</asp:QueryExtender>
为了实现 Version 2,我们首先应该使用 EditCustomerDataSource 的 Selected 事件来获取 Customer_Id 来自 EntityDataSourceSelectedEventArgs,为 Selected 事件提供数据,那么我们可以使用 QueryExtender 使用的 CustomExpression 控制。自定义表达式调用 AddressQueryExtender_Querying 方法,我们应该使用自定义 LINQ 表达式和过滤操作的结果(通过 EntityDataSourceSelectedEventArgs 中的 Customer_Id)将显示在 GridViewAddress 中。
代码隐藏:
~/DynamicData/CustomPages/Customer/Edit.aspx.cs(部分):
protected int customerId;
protected void EditCustomerDataSource_Selected(object sender, EntityDataSourceSelectedEventArgs e)
{
IEnumerable<Customer> customerItem = e.Results.Cast<Customer>();
foreach (Customer c in customerItem)
{
customerId = c.Customer_Id;
}
}
protected void AddressQueryExtender_Querying(object sender, System.Web.UI.WebControls.Expressions.CustomExpressionEventArgs e)
{
e.Query = (from a in e.Query.Cast<Address>()
where a.Customer_Id == customerId
select a);
}
您可以在ASP.NET Dynamic Data Unleashed一书中找到更详细的信息和解释。
【讨论】: