#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
window2. @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, кстати, правильный, а ваш код — нет.