Сортировка asp: ListView, привязанного к EntityDataSource - PullRequest
1 голос
/ 20 февраля 2010

У меня есть элемент управления asp: ListView на странице ASP.NET. Он связан с EntityDataSource , который настроен следующим образом:

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

В SQL Server есть две таблицы: SOrder и Address. У SOrder есть внешний ключ AddressID для таблицы адресов («у заказа один адрес»). Адрес имеет буквенно-цифровое поле «Имя1».

В LayoutTemplate ListView есть кнопка ссылки для сортировки заказов в списке по Name1 из адреса заказа:

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

Если я нажму эту кнопку, я получу EntitySqlException , сообщающую мне, что «Address.Name1» не может быть разрешено в текущем контексте ».

Сортировка по «плоскому» полю таблицы заказов - например, «Код заказа» - работает :

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

Таким образом, исключение возникает только при попытке сортировки по связанному полю в другой таблице. Я ожидал, что при использовании Include = "Address" свойства EntityDataSource сортировка по полям связанного адреса должна быть возможной, но, похоже, нет.

Я сделал тестовый хак, чтобы проверить запрос, который я ожидаю, что EntityDataSource создаст внутренне:

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

Или с помощью 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;
    }
}

Оба работают! Я получаю отсортированный результат.

Теперь я немного растерялся, как заставить эту операцию сортировки работать в ListView. У кого-нибудь есть идея, что я здесь делаю неправильно?

Заранее спасибо!

Ответы [ 2 ]

1 голос
/ 22 февраля 2010

Я нашел решение сам. Все дело в трех пропущенных символах: в моем коде выше это ...

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

... равно НЕПРАВИЛЬНО и должно быть заменено на:

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

Использование "it." для свойств связанных объектов представляется необходимым в отличие от плоских полей. Поэтому во втором примере выше возможны оба пути:

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

То же самое для «идентификаторов объектов» (полей первичного ключа) связанных объектов:

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

Но опять же для связанных свойств, которые не являются идентичностями:

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

Crazy, единственное место, где я мог найти (случайно) указание на это решение, это видео:

Как использовать источник данных сущностей?

... особенно около 9:40 мин видео.

0 голосов
/ 21 февраля 2010

Связанные классы могут не работать CommandArguments или, например, значение DataTextField DropDownList. Вы можете использовать Объекты Передачи Данных для распечатки и сортировки

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