使用动态数据时,“ORDER BY排序键类型必须是可比较的顺序”。

7
我正在尝试创建一个动态数据网站,允许管理员直接编辑数据库中大部分表格中的数据。
到目前为止,我有一个EDMX和POCO类,它们都附加在一个接口上,用于应用字段上的DataAnnotations。
我想为每个表格都有一个可编辑的网格,因此我编辑了ListDetails模板,并按照这些说明进行操作,这使我可以在ListView中进行内联编辑。
通过所有这些,我可以显示和编辑数据。 它有效。
但是当我单击外键列的标题(它是一个LinkButton,带有Sort命令和列名称作为CommandArgument)时,我总是会收到以下异常(但在“简单”属性上排序有效):
[EntitySqlException: ORDER BY排序键的类型必须可排序。在成员访问表达式附近,第6行,第3列。] Microsoft.AspNet.EntityDataSource.EntityDataSourceView.ExecuteSelect(DataSourceSelectArguments arguments) +1325 System.Web.UI.DataSourceView.Select(DataSourceSelectArguments arguments, DataSourceViewSelectCallback callback) +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(Boolean includeStagesBeforeAsyncPoint, Boolean 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,即使排序有效)。看起来它被忽略或在此事件后被替换。异常也没有指定它正在尝试应用的OrderBy,所以我不确定它正在尝试做什么。我尝试实现IComparable但它没有起作用。我重写ToString()方法提供显示值,但也没有起作用。我已经没有想法了,有什么建议吗?
2个回答

1

按照 LOV_LOB.id 或其他 LOVE_LOB 属性进行排序。由于 LOV_LOB 对象本身没有传统的可排序约定,即按数字、日期或字母顺序排序,但它的属性是可以排序的。


我正在使用动态数据,这意味着我没有任何查询,一切都由“EntityDataSource”、“QueryExtender”和“DynamicFilterExpression”自动处理。正如我所提到的,我试图手动强制将“EntityDataSource.OrderBy”设置为对象的任何属性,但似乎被忽略了。 我知道如何在SQL或Entity Framework中对查询进行排序,但我找不到如何在动态数据中实现排序的方法。 - Julien N
1
你尝试过实现IComparable接口吗? - Dexion
是的。没有成功。ToString()也一样。 - Julien N

0

我最终做的:

由于Sort命令无法正常工作,我通过自己指定排序参数来使其正常工作:

在OP中链接的模板中,我将标题中的命令名称CommandName = "Sort"更改为自定义名称CommandName = "CustomSort" 在aspx页面中添加到ListView的映射:OnItemCommand="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;
        }

        //获取列元数据
        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类。

它运行得相当不错。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接