【问题标题】:Change select conditions according to column value根据列值更改选择条件
【发布时间】:2013-12-27 23:23:33
【问题描述】:

我想知道是否可以根据另一列的值来选择我要比较日期时间值的列,例如:

我的模型如下所示:

public class ServicosFinanceiro
{
    [Key]
    public int IdservFin { get; set; }
    public int? ParcelaAtual { get; set; }
    public DateTime? DataVencto1 { get; set; }
    public DateTime? DataVencto2 { get; set; }
    public DateTime? DataVencto3 { get; set; }
    public DateTime? DataVencto4 { get; set; }
}

我想根据 ParcelaAtual 值用 linq 对 DataVencto1 或 DataVencto2 或 DataVencto3 或 DataVencto4 的日期时间范围内的行进行 sql 选择。

如果 ParcelaAtual = 1 我需要比较 DataVencto1 列的日期。 如果 ParcelaAtual = 2 我需要比较 DataVencto2 列的日期等等..

目前我正在选择所有行并执行 foreach 以检查 ParcelaAtual 值是什么,并根据它选择比较相应 DataVencto 列的日期范围并将其添加到另一个模型对象。

是否可以在使用 linq to sql 的 select 语句上实现这一点?

【问题讨论】:

    标签: c# sql-server asp.net-mvc linq-to-sql entity-framework-4


    【解决方案1】:

    做这样的事

    from s in ServicosFinanceiro
    where (s.ParcelaAtual == 1 && s.DataVencto1 >= start && s.DataVencto1 <= end) ||
          (s.ParcelaAtual == 2 && s.DataVencto2 >= start && s.DataVencto2 <= end) ||
          (s.ParcelaAtual == 3 && s.DataVencto3 >= start && s.DataVencto3 <= end) ||
          (s.ParcelaAtual == 4 && s.DataVencto4 >= start && s.DataVencto4 <= end)
    select s
    

    这与我使用纯 T-SQL 所做的类似。

    请注意,startend 是纯 C# 变量,表示您需要查询的日期时间段。

    这可能比在 where 子句上生成 SQL CASE 语句更好(这也应该是可能的)。

    当然,OR statements are not really recommended, perfomance-wise。如果这是一个问题,您应该只编写 4 条 LINQ 语句并结合它们的结果。

    编辑既然你似乎不相信,让我再给你一个选择:

    (
        from s in ServicosFinanceiro
        where (s.ParcelaAtual == 1 && s.DataVencto1 >= start && s.DataVencto1 <= end)
        select s
    ).Union(
        from s in ServicosFinanceiro
        where (s.ParcelaAtual == 2 && s.DataVencto2 >= start && s.DataVencto2 <= end)
        select s
    ).Union(
        from s in ServicosFinanceiro
        where (s.ParcelaAtual == 3 && s.DataVencto3 >= start && s.DataVencto3 <= end)
        select s
    ).Union(
        from s in ServicosFinanceiro
        where (s.ParcelaAtual == 4 && s.DataVencto4 >= start && s.DataVencto4 <= end)
        select s
    )
    

    这将生成一个由 4 个子查询组成的 UNION 语句。这类似于我所说的关于组合 4 个 Linq 查询的内容——但我们正在以这种方式在数据库服务器上执行此操作(并且 SQL Server 优化器将考虑DataVencto1 .. DataVencto2 上的索引)。

    【讨论】:

    • 我尝试使用 CASE,但为什么这种方式比使用 CASE 更好?谢谢
    • 即使您在DataVencto* 列上有索引,CASE 语句也永远不会使用它们。使用 OR 语句有时会更好(我说有时是因为 SQL-Server 也不是很好地优化 OR 谓词 - 它最终也可以进行完整扫描)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-18
    • 2022-11-30
    • 2011-11-12
    • 1970-01-01
    • 2022-01-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多