【问题标题】:Linq to Sql - Incorrect syntax by keyword 'IS'Linq to Sql - 关键字“IS”的语法不正确
【发布时间】:2017-02-16 15:19:52
【问题描述】:

我正在尝试按一列上的空值排序我的查询,然后按 this 帖子中看到的另一列排序。

_ctx.Leads.Include(a => a.LeadAttachments)
    .Where(s => s.Name.ToLower().StartsWith(filter))
    .OrderBy(a=>a.AcceptedOn.HasValue)
    .ThenByDescending(a => a.AssignedOn)
    .Skip(offSet)
    .Take(12)
    .ToList()

添加.OrderBy(a=>a.AcceptedOn.HasValue)时出现此错误

EntityFramework.Core.dll 中出现“System.Data.SqlClient.SqlException”类型的异常,但未在用户代码中处理

附加信息:关键字“IS”附近的语法不正确。

FETCH 语句中选项 NEXT 的使用无效。

我的两个按列排序的类型都是Nullable<DateTime>

这个查询有什么问题?有没有更好的排序方式?

更新:
感谢@vamsi 的回答,我没有这个错误。现在我需要这样排序:
对于AcceptedOn,所有具有null 值的记录都应该排在第一位
所有两个日期都有值的记录应按AssignedOn 而非AcceptedOn 排序
这可能吗?

【问题讨论】:

  • 你能显示这个生成的sql是什么吗?
  • 我该怎么做?
  • 我相信你只是用ToString替换ToList
  • 您是否尝试过 .OrderBy(a=>a.AcceptedOn.Value)
  • @MB - 只需放置 ToString() 而不是 `ToList() - 请参阅 this

标签: c# linq


【解决方案1】:

来自评论:

但我真正想要的是首先所有 null 接受,然后由 AssignedOn 排序。有可能吗

_ctx.Leads.Include(a => a.LeadAttachments)
        .Where(s => s.Name.ToLower().StartsWith(filter))
        .OrderByDescending(a=> a.AcceptedOn == null 
            ? DateTime.MaxValue 
            : a.AssignedOn == null 
                ? a.AcceptedOn 
                : a.AssignedOn)
        .Skip(offSet)
        .Take(12)
        .ToList();

代码解释中的排序优先级

  1. null 值为 AcceptedOn 的记录显示在顶部
  2. 同时具有AcceptedOn 值的记录AND AssignedOn 将按AssignedOn 降序排序
  3. 只有AcceptedOn 值的剩余记录将按降序排列在最后

【讨论】:

  • @GiladGreen - 它们都是日期时间字段。 Op 首先需要所有空条目,然后按 AssignedOn 降序排序。我认为应该这样做。
  • 看起来不错,但是有什么方法可以对AccpetedOn == null 记录进行排序然后通过AssignedOn
  • @MB - 当然,只需更进一步(参见更新),再进行一次空检查。这假设您要对任一类型进行降序排序。
  • 不,像这样。如果AcceptedON == null 然后是最大值然后是assingedon 否则是assignedon
  • @MB - 你在评论中写了assignedon x2。其中哪一个实际上是AssignedOn,哪一个是AcceptedOn
【解决方案2】:

试试看是否可行

 _ctx.Leads.Include(a => a.LeadAttachments)
        .Where(s => s.Name.ToLower().StartsWith(filter))
        .OrderBy(a=>a.AcceptedOn ?? DateTime.MinValue)
        .ThenByDescending(a => a.AssignedOn)
        .Skip(offSet)
        .Take(12)
        .ToList() 

【讨论】:

  • 这行得通,但我真正想要的是首先全部为空acceptedOn,然后由AssignedOn 排序。有可能吗
  • @MB 这正是我的回答正在做的事情。如果 Acceptedon 为 null,则默认为 datetime.minimum 值,即 00.00.0000,因此这些记录首先在列表中,然后是下一个排序顺序
【解决方案3】:

您的问题是您使用 .HasValue,它返回一个布尔值,而您应该使用 .Value,它返回实际值(如果不为空)。

试试这个,我相信它会起作用的......

.OrderBy(a=>a.AcceptedOn.Value)

【讨论】:

  • 您不需要添加.Value。你可以只使用列本身
  • 这不是一回事
【解决方案4】:

这对我来说是完美的工作

_ctx.Leads.Include(a => a.LeadAttachments)
    .Where(s => s.Name.ToLower().StartsWith(filter))
    .OrderByDescending(a=> a.AcceptedOn == null 
        ? DateTime.MaxValue 
        : a.AssignedOn).ThenByDescending(a=>a.AssignedOn)
    .Skip(offSet)
    .Take(12)
    .ToList();

说明:

第一排序:首先获取 null AcceptedOn
然后:按AssignedOn对所有记录排序

【讨论】:

    猜你喜欢
    • 2012-01-12
    • 1970-01-01
    • 1970-01-01
    • 2014-12-10
    • 1970-01-01
    • 1970-01-01
    • 2016-06-08
    • 2020-12-18
    • 1970-01-01
    相关资源
    最近更新 更多