如何从LINQ中实现SQL CASE语句

jjhzyzn0  于 2023-04-09  发布在  其他
关注(0)|答案(4)|浏览(141)

我是新的LINQ,我想知道我是否可以实现下面的SQL查询从LINQ?
使用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调用存储过程,如下所示。我想知道我是否可以在不使用存储过程的情况下做同样的事情?
Copyright © 2018 - 2019 www.cnm.com. All Rights Reserved.粤ICP备15047592号-1
谢谢。

5uzkadbs

5uzkadbs1#

下面是最后一个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 });
1dkrff03

1dkrff032#

可以使用此自定义表达式生成器方法

public static Expression<Func<TEntity, TResult>> SwitchCase<TEntity, TField, TResult>(string fieldName, List<(TField Value, TResult Result)> conditions, TResult defaultValue)
           where TEntity : EntityBase
        {
            // Create parameter expression for TEntity
            var entityParameter = Expression.Parameter(typeof(TEntity), "x");

            // Create expression to extract field property from TEntity
            var fieldExpr = Expression.Convert(Expression.Property(entityParameter, fieldName), typeof(TField));

            // Define default expression for when no conditions match
            var defaultExpr = Expression.Constant(defaultValue);

            // Build conditional expressions by nesting Expression.Condition

            //example x.Status == 0 ? "New" : (x.Status == 1 ? "Active" : "default")
            Expression conditionExpr = defaultExpr;
            for (int i = conditions.Count - 1; i >= 0; i--)
            {
                var mapping = conditions[i];
                var testExpr = Expression.Equal(fieldExpr, Expression.Constant(mapping.Value));
                conditionExpr = Expression.Condition(testExpr, Expression.Constant(mapping.Result), conditionExpr);
            }

            // Create lambda expression for use in LINQ query
            var lambdaExpr = Expression.Lambda<Func<TEntity, TResult>>(conditionExpr, entityParameter);

            return lambdaExpr;
        }

使用方法:

var mappings = new List<(int Number, string Name)>
{
     (0, "New"),
     (1, "Active"),
     (2, "Closed")
};

var result = await context.Entities.OrderBy(CustomExpressionsBuilder.SwitchCase<Entity, int, string>("Status", mappings, "default")).ToListAsync()
holgip5t

holgip5t3#

你可以用这个

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
}
2g32fytz

2g32fytz4#

你可以使用它,如果它适合你。我只会解释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();

EDIT:LINQ Query for grouped result..请确保您使用的是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; }

    }

相关问题