문제

How to create form out of multiple relational entities with Asp.net dynamic data.

E.g. I have a customer table associated with address master. (1 -> 0.1)

I want to show both these entities to a single page while create and editing customer.

How could I achieve this with dynamic data scaffolding.

도움이 되었습니까?

해결책

First of all, you should customize Insert.aspx and Edit.aspx page templates How to: Customize the Layout of an Individual Table By Using a Custom Page Template in order to place on the custom page additional (GridView or FormView) control for showing another entity.

The next step is the following. Consider example of editing customer.

~/DynamicData/CustomPages/Customer/Edit.aspx (partially):

<%-- 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 with Address entity - Version 1 with QueryExtender and DynamicRouteExpression

<%-- 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>

In Version 1 we use a special type of data source expression DynamicRouteExpression. At runtime, this object extracts the values of the primary key columns from the URL and modifies the query generated by the AddressDataSource to include appropriate filter criteria.

It must be noted that the table (entity) Address must include column name Customer_Id(and NOT for example Address_Customer_Id), otherwise GridViewAddress will include all addresses.


GridView with Address entity - Version 2 with QueryExtender with CustomExpression and OnQuerying is more powerful version

<%-- 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>

In order to implement Version 2 we should use, first of all, Selected event of EditCustomerDataSource in order to get Customer_Id from EntityDataSourceSelectedEventArgs, that provides data for the Selected event, then we can use CustomExpression that is used by the QueryExtender control. The custom expression calls the AddressQueryExtender_Querying method, where we should use a custom LINQ expression and the results of the filtering operation (by Customer_Id from EntityDataSourceSelectedEventArgs) will be displayed in a GridViewAddress.

Code-behind:

~/DynamicData/CustomPages/Customer/Edit.aspx.cs (partially):

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);
}

More detailed information and explanations you can find from the book ASP.NET Dynamic Data Unleashed.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top