【问题标题】:How can I achieve SQL CASE statement from LINQ如何从 LINQ 实现 SQL CASE 语句
【发布时间】:2018-03-15 14:25:06
【问题描述】:

我是 LINQ 新手,我想知道我是否可以从 LINQ 实现以下 SQL 查询?

我正在使用 Entity Framework Core。

SELECT 0 [All], [Range] =
    CASE  
        WHEN Value BETWEEN 0 AND 25 THEN 'Low' 
        WHEN Value BETWEEN 25 AND 75 THEN 'Medium' 
        WHEN Value BETWEEN 75 AND 90 THEN 'High' 
        WHEN Value BETWEEN 90 AND 100 THEN 'Very High' 
    END 
FROM Result.Calculation C 
    INNER JOIN Data.SampleSet S ON C.SampleSetID = S.ID  
WHERE  S.SampleDrawn >= DATEADD(MONTH,-3,GETDATE()) AND S.Department = 'LOCATION A'

目前,我正在使用 FromSql 如下调用存储过程。我想知道不使用存储过程是否可以做到这一点?

var 结果 = context.MyData.FromSql("data.GetMyData @pType = {0}, @pLocation = {1}, @pNoOfDays = {2}, @pStartDate = {3}, @pEndDate = {4} ", 类型, 位置, noOfDays, startDate, endDate).ToList();

谢谢。

【问题讨论】:

  • 您能告诉我们您正在使用的现有 EF 查询吗?
  • 你已经尝试了什么?尝试发布一些代码 - 你会得到一个更好的答案。同时发布您的实体类会有所帮助

标签: c# sql linq entity-framework-core


【解决方案1】:

你可以用这个。

from C in Calculations
join S in SampleSets on C.SampleSetID equals S.ID 
where S.SampleDrawn >= DateTime.Now.AddMonths(-3)
      && S.Department == "LOCATION A"
select new {
    All = 1 
    , Range = 
        (C.Value >= 0 && C.Value < 25) ? "Low" :
        (C.Value >= 25 && C.Value < 75) ? "Medium" :
        (C.Value >= 75 && C.Value < 90) ? "High" :
        (C.Value >= 90 && C.Value <= 100) ? "Very High" : null
}

【讨论】:

    【解决方案2】:

    如果它适合你,你可以使用它。 我只想解释一下 LINQ 查询部分。 您可以将其与 EF 一起使用。我为这些创建了虚拟数据。 对于 EF,请改用 IQueryable。

    // from a row in first table
    // join a row in second table
    // on a.Criteria equal to b.Criteria
    // where additional conditions
    // select the records into these two fields called All and Range
    // Convert the result set to list.
    var query = (from a in lstCalc
    join b in lstSampleSet
    on a.SampleSetID equals b.ID where b.SampleDrawn >= DateTime.Now.AddMonths(-8)
    && b.Department == "Location A"
    select new { All = 0, Range = Utilities.RangeProvider(a.Value) }).ToList();
    

    编辑:分组结果的 LINQ 查询。。确保您使用的是 IQueryable。

     var query = (from a in lstCalc
      join b in lstSampleSet
      on a.SampleSetID equals b.ID where b.SampleDrawn >= DateTime.Now.AddMonths(-8) 
       && b.Department == "Location A"
        group a by Utilities.RangeProvider(a.Value) into groupedData
         select new Result { All = groupedData.Sum(y => y.Value), Range = 
       groupedData.Key }).ToList();
    

    这是相同的代码。

     public class Program
        {
            public static void Main(string[] args) {
                List<Calculation> lstCalc = new List<Calculation>();
                lstCalc.Add(new Calculation() {SampleSetID=1, Value=10 });
                lstCalc.Add(new Calculation() { SampleSetID = 1, Value = 10 });
                lstCalc.Add(new Calculation() { SampleSetID = 2, Value = 20 });
                lstCalc.Add(new Calculation() { SampleSetID = 3, Value = 30 });
                lstCalc.Add(new Calculation() { SampleSetID = 4, Value = 40 });
                lstCalc.Add(new Calculation() { SampleSetID = 5, Value = 50 });
                lstCalc.Add(new Calculation() { SampleSetID = 6, Value = 60 });
                lstCalc.Add(new Calculation() { SampleSetID = 7, Value = 70 });
                lstCalc.Add(new Calculation() { SampleSetID = 8, Value = 80 });
                lstCalc.Add(new Calculation() { SampleSetID = 9, Value = 90 });
    
                List<SampleSet> lstSampleSet = new List<SampleSet>();
                lstSampleSet.Add(new SampleSet() {Department = "Location A", ID=1, SampleDrawn=DateTime.Now.AddMonths(-5)});
                lstSampleSet.Add(new SampleSet() { Department = "Location A", ID = 2, SampleDrawn = DateTime.Now.AddMonths(-4) });
                lstSampleSet.Add(new SampleSet() { Department = "Location A", ID = 3, SampleDrawn = DateTime.Now.AddMonths(-3) });
                lstSampleSet.Add(new SampleSet() { Department = "Location A", ID = 4, SampleDrawn = DateTime.Now.AddMonths(-2) });
                lstSampleSet.Add(new SampleSet() { Department = "Location A", ID = 5, SampleDrawn = DateTime.Now.AddMonths(-2) });
                lstSampleSet.Add(new SampleSet() { Department = "Location A", ID = 6, SampleDrawn = DateTime.Now.AddMonths(-2) });
                lstSampleSet.Add(new SampleSet() { Department = "Location A", ID = 7, SampleDrawn = DateTime.Now.AddMonths(-1) });
    
                var query = (from a in lstCalc
                            join b in lstSampleSet
                            on a.SampleSetID equals b.ID where b.SampleDrawn >= DateTime.Now.AddMonths(-8)
                             && b.Department == "Location A"
                            select new { All = 0, Range = Utilities.RangeProvider(a.Value) }).ToList();
    
                Console.WriteLine(query.Count);
                Console.ReadLine();
    
            }
    
    
        }
    
            public class Utilities
            {
                public static string RangeProvider(int value)
                {
                    if (value > 0 && value <= 25)
                    { return "Low"; }
                    if (value > 25 && value <= 75)
                    { return "Medium"; }
                    if (value > 75 && value <= 90)
                    { return "High"; }
                    else
                    { return "Very High"; }
                }
    
            }
    
        public class Result {
          public int All { get; set; }
          public string Range { get; set; }
       }
    
        public class Calculation
        {
            public int SampleSetID { get; set; }
            public int Value { get; set; }
    
        }
    
        public class SampleSet
        {
            public int ID { get; set; }
            public DateTime SampleDrawn { get; set; }
    
            public string Department { get; set; }
    
        }
    

    【讨论】:

    • 是的,linq 部分将保持不变。你可以试试看。
    • @Amit:谢谢。那行得通。您能否也让我知道如何将 linq 语句扩展到 Group By Range 列?
    • @ChiranthaWanasinghe 添加了对分组结果的查询。
    • @Amit:不用担心,我想通了。谢谢大家的帮助。
    • @Amit:哦,太好了。谢谢。
    【解决方案3】:

    下面是对我有用的最终 LINQ 语句。正如 Amit 在他的回答中解释的那样,RangeProvider 方法将用于替换 SQL CASE 语句。

    var test2 = (from a in context.Calculations
                             join b in context.SampleSets on a.SampleSetID equals b.ID
                             where b.SampleDrawn >= DateTime.Now.AddDays(-10) && b.Department == "Location A"
                             group a by RangeProvider(a.Value) into groupedData
                             select new { All = groupedData.Count(), Range = groupedData.Key });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-07
      • 2020-06-11
      • 1970-01-01
      相关资源
      最近更新 更多