【问题标题】:Sorting an asp:ListView bound to an EntityDataSource对绑定到 EntityDataSource 的 asp:ListView 进行排序
【发布时间】:2010-02-20 20:59:27
【问题描述】:

我在 ASP.NET 页面上有一个 asp:ListView 控件。它绑定到以这种方式设置的 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 到地址表(“一个订单有一个地址”)。该地址有一个字母数字字段“Name1”。

在ListView的LayoutTemplate中有一个链接按钮,用于按照订单地址的Name1对列表中的订单进行排序:

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

如果我单击此按钮,我会收到一个 EntitySqlException,告诉我“'Address.Name1' 无法在当前上下文中解析”。

按订单表的“平面”字段排序 - 例如“OrderCode” - 有效

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

所以只有当我尝试按另一个表中的相关字段排序时才会发生异常。我期望使用 EntityDataSource 的 Include="Address" 属性按相关地址的字段排序应该是可能的,但似乎不是。

我做了一个测试来检查我希望 EntityDataSource 在内部创建的查询:

使用 Linq 到实体:

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

或者使用实体 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 中进行这种排序操作。有人知道我在这里做错了什么吗?

提前谢谢你!

【问题讨论】:

    标签: asp.net entity-framework sorting listview entitydatasource


    【解决方案1】:

    我自己找到了解决方案。这都是缺少三个字符的问题:在我上面的代码中,这个...

    <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
    

    疯了,我唯一能(偶然)找到这个解决方案的迹象的地方就是这个视频:

    How Do I Use the Entity Data Source?

    ...尤其是在视频的 9:40 分钟左右。

    【讨论】:

    • +1 为我解决了同样的问题。感谢您发布对此问题的解决方案!
    【解决方案2】:

    关联的类可能无法使用 CommandArguments 或例如 DropDownList 的 DataTextField 值。您可以使用数据传输对象进行列表和排序

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

    【讨论】:

    • 感谢您的反馈!一个问题:我必须将带有 LINQ 查询的代码放在哪里?在排序事件的事件处理程序内部?还是在 CommandName 事件中?我是否需要将 LINQ 查询的结果分配给 ListView 作为新的数据源?
    • 如果您不想进行表达式排序,请写入 Page_Load 并将“结果”绑定到您的控件。或者你想自动排序,所以,网格可以按所有列排序 - 作为客户请求,我将在这里编写新代码让我知道。
    • 我已经用 GridView 测试过了。但它具有基本相同的问题,因为我无法将“Address.Name1”之类的关联字段绑定到列。我可以使用带有包含 Eval("Address.Name1") 的标签的模板字段。到目前为止,这有效,相关字段显示在网格中。但是在模板字段中声明性地我必须指定一个 SortExpression 来对列进行排序,并且在该 SortExpression 中使用“Address.Name1”我得到了同样的异常。
    • 我理解将 LINQ 查询的“结果”绑定到 Page_Load 中的 ListView 控件的想法。但后来我失去了 EntityDataSource 的所有内置功能 - 特别是分页和编辑。它会迫使我手动编写所有这些东西,这是我想避免的。
    • 如我所说。您不能将关联字段用于某些控制操作。您必须处理 LinkBut​​ton 的单击或绑定类。如果您将使用 dto,您可以将 ObjectDataSource 添加到您的页面。和 entitydatasource 一样,排序列表,但是你必须写方法和 linq。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-29
    • 2011-09-25
    • 1970-01-01
    • 1970-01-01
    • 2017-09-20
    • 2013-08-30
    • 2018-05-18
    相关资源
    最近更新 更多