简体   繁体   English

如何从 LINQ 实现 SQL CASE 语句

[英]How can I achieve SQL CASE statement from LINQ

I am new to LINQ and I would like to know if I can achieve the below SQL query from LINQ?我是 LINQ 的新手,我想知道我是否可以从 LINQ 实现以下 SQL 查询?

I am using 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'

Currently, I am using FromSql as below to call a stored procedure.目前,我使用 FromSql 如下调用存储过程。 I would like to know whether I can do the same without using stored procedures?我想知道是否可以在不使用存储过程的情况下做同样的事情?

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

Thanks.谢谢。

You can use this.你可以用这个。

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
}

You can use this if it suits you.如果它适合您,您可以使用它。 I would just explain the LINQ query part.我只想解释 LINQ 查询部分。 You can use this with EF.您可以将其与 EF 一起使用。 I created dummy data for these.我为这些创建了虚拟数据。 For EF, use IQueryable instead.对于 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();

EDIT : LINQ Query for grouped result.编辑:LINQ 查询分组结果。 . . Make sure you are using IQueryable.确保您使用的是 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();

Here is the code for the same.这是相同的代码。

 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; }

    }

Below is the final LINQ statement which worked for me.以下是对我有用的最终 LINQ 语句。 As Amit explain in his answer RangeProvider method will be used to replace the SQL CASE statement.正如 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 });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM