【问题标题】:"The ORDER BY sort key(s) type must be order-comparable" with dynamic data“ORDER BY 排序键类型必须与动态数据具有顺序可比性”
【发布时间】:2016-08-21 19:09:35
【问题描述】:

我正在尝试创建一个动态数据网站,它应该允许管理员直接编辑数据库中大多数表中的数据。

到目前为止,我有一个 EDMX 和 POCO 类,它们都附加到一个接口,用于在字段上应用 DataAnnotations。
我想为每个表创建一个可编辑的网格,因此我编辑了 ListDetails 模板并遵循these instructions,它允许我在 ListView 中进行内联编辑。
有了所有这些,我可以显示和编辑数据。有用。

但是当我单击 ForeignKey 列的标题(它是带有 Sort 命令的 LinkButton 和作为 CommandArgument 的列名)时,我总是得到以下异常(但排序工作在“简单”属性):

[EntitySqlException: ORDER BY 排序键类型必须是 订单可比。近成员访问表达式,第 6 行,第 3 列。]
Microsoft.AspNet.EntityDataSource.EntityDataSourceView.ExecuteSelect(DataSourceSelectArguments 论据)+1325
System.Web.UI.DataSourceView.Select(DataSourceSelectArguments 参数,DataSourceViewSelectCallback 回调)+21
System.Web.UI.WebControls.DataBoundControl.PerformSelect() +138
System.Web.UI.WebControls.ListView.PerformSelect() +167
System.Web.UI.WebControls.BaseDataBoundControl.DataBind() +30
System.Web.UI.WebControls.BaseDataBoundControl.EnsureDataBound() +105 System.Web.UI.WebControls.BaseDataBoundControl.OnPreRender(EventArgs e) +22 System.Web.UI.Control.PreRenderRecursiveInternal() +83
System.Web.UI.Control.PreRenderRecursiveInternal() +155
System.Web.UI.Control.PreRenderRecursiveInternal() +155
System.Web.UI.Control.PreRenderRecursiveInternal() +155
System.Web.UI.Control.PreRenderRecursiveInternal() +155
System.Web.UI.Control.PreRenderRecursiveInternal() +155
System.Web.UI.Control.PreRenderRecursiveInternal() +155
System.Web.UI.Page.ProcessRequestMain(布尔值 includeStagesBeforeAsyncPoint,布尔型 includeStagesAfterAsyncPoint) +974

我正在尝试显示和排序的表格示例(我正在显示和编辑 LINK_ENTITES_MODELISEES,我正在尝试对 LOV_LOB 列进行排序):

[MetadataType(typeof(ILINK_ENTITES_MODELISEES_MetaData))]
public partial class LINK_ENTITES_MODELISEES : ILINK_ENTITES_MODELISEES_MetaData
{
    public int id_entite_modelisee { get; set; }
    public short id_entite { get; set; }
    public short id_lob { get; set; }
    public System.DateTime date_val_debut { get; set; }
    public System.DateTime date_val_fin { get; set; }

    public virtual LOV_ENTITE LOV_ENTITE { get; set; }
    public virtual LOV_LOB LOV_LOB { get; set; }
}

public partial interface ILINK_ENTITES_MODELISEES_MetaData
{
    [Key]
    [Required(ErrorMessage = "id_entite_modelisee is required")]
    int id_entite_modelisee { get; set; }

    [Required(ErrorMessage = "id_entite is required")]
    short id_entite { get; set; }

    [Required(ErrorMessage = "id_lob is required")]
    short id_lob { get; set; }

    [Required(ErrorMessage = "date_val_debut is required")]
    [DataType(DataType.Date)]
    System.DateTime date_val_debut { get; set; }

    [Required(ErrorMessage = "date_val_fin is required")]
    [DataType(DataType.Date)]
    System.DateTime date_val_fin { get; set; }

    [Display(Name = "entite")]
    LOV_ENTITE LOV_ENTITE { get; set; }

    [Display(Name = "lob")]
    LOV_LOB LOV_LOB { get; set; }
}

[MetadataType(typeof(ILOV_LOB_MetaData))]
[DisplayColumn("libelle", "libelle", false)]
public partial class LOV_LOB : ILOV_LOB_MetaData
{
    public short id { get; set; }
    public string libelle { get; set; }
    public System.DateTime date_val_debut { get; set; }
    public System.DateTime date_val_fin { get; set; }
}

public partial interface ILOV_LOB_MetaData
{
    [Key]
    [Required(ErrorMessage = "id is required")]
    short id { get; set; }

    [Required(ErrorMessage = "libelle is required")]
    [StringLength(5)]
    string libelle { get; set; }

    [Required(ErrorMessage = "date_val_debut is required")]
    [DataType(DataType.Date)]
    System.DateTime date_val_debut { get; set; }

    [Required(ErrorMessage = "date_val_fin is required")]
    [DataType(DataType.Date)]
    System.DateTime date_val_fin { get; set; }
}

它可能不起作用,因为它试图对对象属性而不是它使用的标签进行排序,但我希望动态数据能够处理它(它使用第一个字符串属性作为显示值,为什么不能它用于排序吗?此外,我还尝试添加 DisplayColumn 属性,结果相同)。

我尝试处理事件ListView.OnSorting 手动编辑EntityDataSource.OrderBy 属性,手动添加值it.LOV_LOB.libelle 进行测试。它没有用。 我还尝试处理 EntityDataSource.OnSelecting 以查看 EntityDataSource.OrderBy 的值是什么(如果我不手动设置它,即使排序工作也总是null)。看起来它在此事件之后被忽略或替换。并且 Exception 没有指定它试图应用什么 OrderBy,所以我不确定它试图做什么。 我尝试实现IComparable,但没有成功。 我重写了 ToString() 来提供显示值,它也不起作用。

我想不通。有什么建议吗?

【问题讨论】:

    标签: c# asp.net entity-framework sorting asp.net-dynamic-data


    【解决方案1】:

    LOV_LOB.id 或其他LOVE_LOB 属性之一排序。由于 LOV_LOB 对象本身不能按常规排序,即按数字或日期时间或字母顺序,但它的属性是。

    【讨论】:

    • 我在这里使用的是动态数据,这意味着我没有任何查询,一切都由EntityDataSourceQueryExtenderDynamicFilterExpression 自动处理。正如我所提到的,我试图手动将EntityDataSource.OrderBy 强制为对象的任何属性,但它似乎被忽略了。我知道如何在 SQL 或实体框架中对查询进行排序,但我找不到如何使用动态数据进行排序。
    • 你试过实现IComparable接口吗?
    • 是的。没有成功。 ToString() 也是。
    【解决方案2】:

    我最终做了什么:

    由于Sort 命令不起作用,我通过自己指定排序参数使其起作用:

    • 在 OP 中链接的模板中,我将标题 CommandName = "Sort" 中的命令名称更改为自定义的 CommandName = "CustomSort"
    • 将映射添加到aspx页面中的ListViewOnItemCommand="ListView1_ItemCommand"
    • 在 CodeBehind 页面中,我处理了自定义命令(我知道,将信息存储在 Session 中是个坏主意。请参阅 this question):

      protected void ListView1_ItemCommand(object sender, ListViewCommandEventArgs e)
      {
          if (e.CommandName == "CustomSort")
          {
              var sortInfos = Session["SortInfos"] as SortInfos;
              var sortDirection = SortDirection.Ascending;
              if (sortInfos != null && sortInfos.Sort == e.CommandArgument.ToString())
              {
                  sortDirection = sortInfos.SortDirection.HasValue && sortInfos.SortDirection == SortDirection.Ascending ? SortDirection.Descending : SortDirection.Ascending;
              }
      
              //Get columns metadata
              var data = table.Columns.SingleOrDefault(c => c.Name == e.CommandArgument.ToString());
      
              string filter = null;
              if (data is MetaForeignKeyColumn)
                  filter = String.Format("{0} {1}", data.SortExpression, sortDirection == SortDirection.Ascending ? "asc" : "desc");
              else
                  filter = String.Format("it.{0} {1}", data.SortExpression, sortDirection == SortDirection.Ascending ? "asc" : "desc");
      
              GridDataSource.OrderBy = filter;
              GridDataSource.AutoGenerateOrderByClause = false;
      
              Session["SortInfos"] = new SortInfos() { Sort = e.CommandArgument.ToString(), SortDirection = sortDirection };
          }
      }
      

      GridDataSource 是我的 EntityDataSource 对象。
      SortInfos 只是一个带有 SortSortDirection 属性的 POCO 类

    效果很好。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-12-22
      • 2017-06-03
      • 1970-01-01
      • 2011-04-06
      • 1970-01-01
      相关资源
      最近更新 更多