Question

I have an asp:ListView control on an ASP.NET page. It is bound to an EntityDataSource which is setup this way:

<asp:EntityDataSource ID="EntityDataSourceOrders" runat="server" 
        ConnectionString="name=EntitiesContext" 
        DefaultContainerName="EntitiesContext" EntitySetName="SOrder" 
        Include="Address"
        EnableDelete="True" EnableInsert="True" 
        EnableUpdate="True">
</asp:EntityDataSource>

In SQL Server there are two tables, SOrder and Address. SOrder has a foreign key AddressID to the Address table ("an order has one address"). The address has an alphanumeric field "Name1".

In the LayoutTemplate of the ListView is a link button to sort the orders in the list by Name1 of the order's address:

<asp:LinkButton runat="server" ID="SortButtonName" Text="Name"
                CommandName="Sort" CommandArgument="Address.Name1" />

If I click this button I get an EntitySqlException telling me that "'Address.Name1' could not be resolved in the current context".

Sorting by a "flat" field of the order table - for instance "OrderCode" - works:

<asp:LinkButton runat="server" ID="SortButtonOrderCode" Text="Order number"
                CommandName="Sort" CommandArgument="OrderCode" />

So the exception occurs only when I try to sort by an related field in another table. I was expecting that with the Include="Address" property of the EntityDataSource sorting by fields of the related address should be possible, but it seems not.

I've made a test hack to check the query I expect the EntityDataSource to create internally:

With Linq to Entities:

using (EntitiesContext ctx = new EntitiesContext())
{
    var result = from order in ctx.SOrder.Include("Address")
                 orderby order.Address.Name1
                 select order;

    foreach (SOrder x in result)
    {
        string test=x.Address.Name1;
    }
}

Or with Entity SQL:

string queryString = @"SELECT VALUE x FROM SOrder AS x
                     Order By x.Address.Name1";
using (EntitiesContext ctx = new EntitiesContext())
{
    ObjectQuery<SOrder> query = 
        new ObjectQuery<SOrder>(queryString, ctx).Include("Address");

    foreach (SOrder x in query.Execute(MergeOption.AppendOnly))
    {
        string test=x.Address.Name1;
    }
}

Both works! I get a sorted result.

Now I am a bit lost how I get this sort operation working in the ListView. Does somebody have an idea what I am doing wrong here?

Thank you in advance!

Was it helpful?

Solution

I found the solution myself. It's all a matter of three missing characters: In my code above, this ...

<asp:LinkButton runat="server" ID="SortButtonName" Text="Name"
                CommandName="Sort" CommandArgument="Address.Name1" />

...is WRONG and has to be replaced by:

<asp:LinkButton runat="server" ID="SortButtonName" Text="Name"
                CommandName="Sort" CommandArgument="it.Address.Name1" />

Using "it." for properties of related objects seems to be necessary in contrast to flat fields. Therefore in the second example above both ways are possible:

CommandArgument="it.OrderCode" // works
CommandArgument="OrderCode"    // works as well

The same for "object identities" (primary key fields) of related objects:

CommandArgument="it.Address.AddressID" // works
CommandArgument="Address.AddressID"    // works as well

But again for related properties which are not identities:

CommandArgument="it.Address.Name1" // works
CommandArgument="Address.Name1"    // does NOT work

Crazy, the only place where I could find (accidentally) an indication to this solution, is this video:

How Do I Use the Entity Data Source?

...especially at around 9:40 min of the video.

OTHER TIPS

Associated classes may wont work CommandArguments or eg DropDownList's DataTextField value. You may use Data Transfer Objects for listing and sorting

public class OrderDTO
{
    public string AddressName1 {get;set;}
}

using (EntitiesContext ctx = new EntitiesContext())
{
    var result = from order in ctx.SOrder
                 let dto = new OrderDTO
                            {
                                  AddressName1 = order.Address.Name1
                                  //bla bla
                            };
                 orderby dto.AddressName1
                 select dto;
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top