【问题标题】:SQL Tuple Comparison in EntityFramework CoreEntityFramework Core 中的 SQL 元组比较
【发布时间】:2020-09-23 06:51:09
【问题描述】:

问题

是否可以在 C# 中使用带有 EF Core 的 LINQ 执行 SQL Tuple Comparison

更多信息

预期的 SQL 结果

SELECT * FROM Locations
WHERE (Locations.Id,Locations.Created) >= ("08d85dba-eb22-4fb4-8868-f833a1403bec","2020-09-20 23:09:55.885263")
ORDER BY Locations.Created 
LIMIT 10;

我特别关心的是WHERE 子句表达式,我将其称为Tuple Comparison

WHERE (Locations.Id,Locations.Created) >= ("08d85dba-eb22-4fb4-8868-f833a1403bec","2020-09-20   23:09:55.885263")

我使用 LINQ 尝试了多种方法,但 C# 编译器总是以失败告终,因为 >= 运算符和 C# 不知道如何比较它。

原因

我正在尝试做一个Tuple Comparison 来从这个post 实现基于光标的分页。

现在我将使用存储过程,我只是想知道它是否可能

【问题讨论】:

  • 总是以失败告终。这不是答案吗?我不认为 EF 会投资 SQL Server 不支持的功能(都来自微软,太尴尬了)。此外,我认为 C# 和 SQL 之间支持的运算符不匹配是一个主要障碍。
  • 这对你的情况不起作用Locations.Id == "08d85dba-eb22-4fb4-8868-f833a1403bec" && Locations.Created >= "2020-09-20 23:09:55.885263"
  • 附注。为什么要比较一个 guid 是否等于或大于另一个 guid?我想如果它们是连续的是有道理的,但是创建日期本身就足够了。
  • @GertArnold 那是基于我对 LINQ、C# 和 SQL 的了解,只是想看看是否有人有我不知道的方法。不过你说的有道理。我也不是 SQL 专家,不确定元组比较在 SQL 中的含义。它是独一无二的还是某种东西的简写?
  • @NicholasMata 这是简写。 (a, b) >= (1, 2)a > 1 OR (a == 1 AND b >= 2) 基本相同。虽然我不确定元组在索引策略中的表现如何。

标签: c# mysql entity-framework linq asp.net-core


【解决方案1】:

感谢@404 的评论,我能够运行一些测试并编写一个 LINQ 表达式

解决方案

var someDate = new DateTime("2020-09-23 12:40:58");
query.Where(l => l.Created >= someDate && (string.CompareTo(l.Id, "1bb50ac7-4d8e-4493-9b15-e1997a") >= 0 || l.Created >= someDate));

注意:我需要验证此语句输出的 sql,但据我所知,这应该根据 Unsupported System.String Non-static Methods 工作

SQL 验证

假设我有一个名为 Locations 的表,其中包含以下数据。

[
    {"id": "1b859e3c-d512-47e4-8ef0-106165", "created": "2020-09-23 12:38:34"},
    {"id": "1bb50ac7-4d8e-4493-9b15-e1997a", "created": "2020-09-23 12:40:58"},
    {"id": "35626ffe-d84e-4543-8734-89dbda", "created": "2020-09-22 12:40:58"},
    {"id": "ada06b5f-a9ca-4bc3-9b61-105e89", "created": "2020-09-25 12:40:58"},
    {"id": "c34b21d1-19ea-48b9-bee8-f201d6", "created": "2020-09-23 12:40:58"},
    {"id": "f68064c7-6617-46c4-b19c-e70b25", "created": "2020-09-23 12:38:33"}
]

排序结果

SELECT *
FROM Locations
ORDER BY Locations.created ASC, Locations.id ASC;
-- Results
-- [
--     {"id": "35626ffe-d84e-4543-8734-89dbda", "created": "2020-09-22 12:40:58"},
--     {"id": "f68064c7-6617-46c4-b19c-e70b25", "created": "2020-09-23 12:38:33"},
--     {"id": "1b859e3c-d512-47e4-8ef0-106165", "created": "2020-09-23 12:38:34"},
--     {"id": "1bb50ac7-4d8e-4493-9b15-e1997a", "created": "2020-09-23 12:40:58"},
--     {"id": "c34b21d1-19ea-48b9-bee8-f201d6", "created": "2020-09-23 12:40:58"},
--     {"id": "ada06b5f-a9ca-4bc3-9b61-105e89", "created": "2020-09-25 12:40:58"}
-- ]

元组比较

SELECT *
FROM Location
WHERE (Location.created, Location.id) >= ("2020-09-23 12:40:58", "1bb50ac7-4d8e-4493-9b15-e1997a")
ORDER BY Location.created ASC, Location.id ASC
LIMIT 4;
-- Results
-- [
--     {"id": "1bb50ac7-4d8e-4493-9b15-e1997a", "created": "2020-09-23 12:40:58"},
--     {"id": "c34b21d1-19ea-48b9-bee8-f201d6", "created": "2020-09-23 12:40:58"},
--     {"id": "ada06b5f-a9ca-4bc3-9b61-105e89", "created": "2020-09-25 12:40:58"}
-- ]

@404 专门设计的长句

SELECT *
FROM Location
WHERE Location.created >= "2020-09-23 12:40:58" AND  (Location.id >= "1bb50ac7-4d8e-4493-9b15-e1997a" OR Location.created >= "2020-09-23 12:40:58")
ORDER BY Location.created ASC, Location.id ASC
LIMIT 4;
-- Results
-- [
--     {"id": "1bb50ac7-4d8e-4493-9b15-e1997a", "created": "2020-09-23 12:40:58"},
--     {"id": "c34b21d1-19ea-48b9-bee8-f201d6", "created": "2020-09-23 12:40:58"},
--     {"id": "ada06b5f-a9ca-4bc3-9b61-105e89", "created": "2020-09-25 12:40:58"}
-- ]

【讨论】:

  • 这似乎不正确。它基本上只检查 Location.created 。如果 Location.craeted >= x,则 (Location.id >= y OR Location.created >= x) 始终为真。我认为您需要在最后一个比较中使用 > 而不是 >=。
猜你喜欢
  • 1970-01-01
  • 2011-07-27
  • 1970-01-01
  • 2019-10-06
  • 1970-01-01
  • 1970-01-01
  • 2011-10-18
  • 2022-01-10
  • 1970-01-01
相关资源
最近更新 更多