Преобразование SQL в LINQ на c#

#c# #sql-server #linq #entity-framework-core

#c# #sql-сервер #linq #сущность-фреймворк-ядро

Вопрос:

Я не могу записать приведенный ниже запрос в Linq.

 SELECT  
  dateentered,  
  sum(Advance) AS amount,  
  CAST(100 * sum(sum(Advance)) OVER (ORDER BY dateentered) 
     / sum(sum(Advance)) OVER () AS numeric(10, 2)) AS percentage 
FROM Portfolio WHERE [Date Funded]>='12/1/2015' and [Date Funded]<='11/30/2020' 
GROUP BY dateentered
 

Я могу выполнять в SQL, но не могу преобразовать в linq. Подробнее я использовал linqer для преобразования, но он также не работает.

Комментарии:

1. Вы когда-нибудь пробовали вводить этот запрос в linq? Если вы пробовали, поделитесь с нами, где у вас были проблемы, какую именно часть вы не можете выполнить.

2. похоже, это сложная задача (хотя на вашем месте это было бы легко).

3. Не все в SQL имеет эквивалент LINQ. Это пример.

4. Чаще всего лучше просто использовать необработанный SQL, чем пытаться обмануть LINQ, чтобы создать именно этот запрос.

5. У вас отличный SQL. В EF Core есть API для выполнения такого SQL. Перевод не требуется и даже не желателен. Иногда правильный ответ на вопрос «как?» просто: «не надо»

Ответ №1:

Язык SQL ограничен, и часто вам приходится использовать kludges для получения требуемых результатов. c # — гораздо более надежный язык. Вот моя модель запроса

     class Program
    {
        static void Main(string[] args)
        {
            Context db = new Context();

            var results = db.Portfolio.Where(x => (x.Date_Funded.Date >= DateTime.Parse("12/1/2015")) amp;amp; (x.Date_Funded.Date <= DateTime.Parse("11/39/2020")))
                .OrderBy(x => x.dateentered)
                .GroupBy(x => x.dateentered.Date)
                .Select(x => new { dateentered = x.Key, sum = x.Sum(y => y.Advance) })
                .Select(x => new
                {
                    dateentered = x.dateentered,
                    amount = x.sum,
                    percentage = Math.Round((100 * x.sum), 2)
                }).ToList();

            
        }
    }
    public class Context
    {
        public List<Portfolio> Portfolio { get; set; }
    }
    public class Portfolio
    {
        public DateTime dateentered { get; set; }
        public decimal Advance { get; set; }
        public DateTime Date_Funded { get; set; }

    }
 

Комментарии:

1. Это не учитывает функцию OVER window

2. @Charlieface: Оригинал также делает что-нибудь с ОКОНЧАНИЕМ. Я не думаю, что исходный SQL на самом деле работает так, как этого хочет OP. Я просто перевел исходный SQL как можно лучше.

3. DateTime.Parse("12/1/2015") Как правило, я бы рекомендовал использовать DateTime конструктор (или использовать ParseExact ), а также перемещать эту логику за пределы запроса LINQ (т. Е. Помещать ее раньше).

4. Не уверен, что вы правы, у него есть 100 * sum( sum(Advance) ) OVER (ORDER BY dateentered) / sum( sum(Advance) ) OVER () , который, если я не ошибаюсь, даст текущий процент sum(advance)

5. Язык SQL ограничен — почему? Это очень выразительно. То, что требует целого блока императивного кода C #, он выполняет в одном декларативном операторе. OP даже не должен хотеть «конвертировать» его в LINQ. Оператор SQL, кстати, правильный, а ваш код — нет.