Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM Новый топик    Ответить
 Оптимизация EF Core 2.0  [new]
gr
Member

Откуда:
Сообщений: 29
Добрый день.

Продолжаю изучение EF Core 2.0.

Есть два класса
public class PR_Account
    {
        public string No { get; set; }
        public string Name { get; set; }
        public int AccountType { get; set; }
        public byte Blocked { get; set; }
        public byte DirectPosting { get; set; }
        public int Indentation { get; set; }
        public string Totaling { get; set; }
        public int Type { get; set; }
    }

public class PR_GLEntry
    {
        public int EntryNo { get; set; }
        public string AccountNo { get; set; }
        public decimal Amount { get; set; }
        public string DocumentNo { get; set; }
        public string Description { get; set; }
        public string BalAccountNo { get; set;        }
        public int BalAccountType { get; set; }
        public int SourceType { get; set; }
        public string SourceNo { get; set; }
        public DateTime PostingDate { get; set; }
        public DateTime DocumentDate { get; set; }
    }


Мне нужно получить запрос типа:
SELECT [No]
      ,[Name]
      ,(select sum([Amount])
	    from [dbo].[PR_GLEntries] G
		where G.[AccountNo] = A.No)
  FROM [Pronet2].[dbo].[PR_Accounts] A


Я получаю результат методом GetByDate:
   public class AccountSum
    {
        public PR_Account Account { get; set; }
        public decimal Sum { get; set; }

        public static List<AccountSum> GetByDate(PRContext db, DateTime reportDate)
        {
            var res = db.PR_Accounts.GroupJoin(db.PR_GLEntries
                , a => a.No
                , g => g.AccountNo
                , (acc, sumAcc) =>
                new AccountSum { Account = acc, Sum = sumAcc.Sum(ga => ga.Amount) }).ToList();

            return res;
         }
    }


Результат правильный! Да вот беда, к БД идет обращение в виде:
SELECT [a].[No], [a].[AccountType], [a].[Blocked], [a].[DirectPosting], [a].[Indentation], [a].[Name], [a].[Totaling], [a].[Type], [g].[EntryNo], [g].[AccountNo], [g].[Amount], [g].[BalAccountNo], [g].[BalAccountType], [g].[Description], [g].[DocumentDate], [g].[DocumentNo], [g].[PostingDate], [g].[SourceNo], [g].[SourceType]
FROM [PR_Accounts] AS [a]
LEFT JOIN [PR_GLEntries] AS [g] ON [a].[No] = [g].[AccountNo]
ORDER BY [a].[No]


Т.е. все строки передаются в приложение. Это совсем не то что я хотел! Как написать команду, что бы она соответствовала ожидаемому запросу (без выборки всех строк)?
20 июл 18, 11:22    [21587861]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация EF Core 2.0  [new]
Shocker.Pro
Member

Откуда: ->|<- :адуктО
Сообщений: 19550
Так в требуемом запросе тоже будут выбираться все строки
SELECT [No]
      ,[Name]
      ,(select sum([Amount])
	    from [dbo].[PR_GLEntries] G
		where G.[AccountNo] = A.No)
  FROM [Pronet2].[dbo].[PR_Accounts] A
никакого фильтра не видно
20 июл 18, 11:29    [21587897]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация EF Core 2.0  [new]
gr
Member

Откуда:
Сообщений: 29
Shocker.Pro,

EF Core берет из БД все записи из обоих таблиц:
SELECT [a].[No], [a].[AccountType], [a].[Blocked], [a].[DirectPosting], [a].[Indentation], [a].[Name], [a].[Totaling], [a].[Type],
 [g].[EntryNo], [g].[AccountNo], [g].[Amount], [g].[BalAccountNo], [g].[BalAccountType], [g].[Description], [g].[DocumentDate], 
[g].[DocumentNo], [g].[PostingDate], [g].[SourceNo], [g].[SourceType]
FROM [PR_Accounts] AS [a]
LEFT JOIN [PR_GLEntries] AS [g] ON [a].[No] = [g].[AccountNo]
ORDER BY [a].[No]


А мне нужны все записи из первой и суммы по второй. В первой всего несколько десятков записей, а во второй сотни тысяч...
SELECT [No]
      ,[Name]
      ,(select sum([Amount])
	    from [dbo].[PR_GLEntries] G
		where G.[AccountNo] = A.No)
  FROM [Pronet2].[dbo].[PR_Accounts] A
20 июл 18, 11:49    [21588013]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация EF Core 2.0  [new]
Shocker.Pro
Member

Откуда: ->|<- :адуктО
Сообщений: 19550
EF Core не умеет даже Groupby, не умеет и проекции нормально делать, увы
20 июл 18, 12:02    [21588068]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация EF Core 2.0  [new]
gr
Member

Откуда:
Сообщений: 29
Shocker.Pro,

Не, самые простые запросы он группирует. Вот такой запрос он нормально обрабатывает:
var accsSum = (from o in db.PR_GLEntries
                           where o.PostingDate <= reportDate
                           group o by o.AccountNo into os
                           select new AccountSumShort { AccountNo = os.Key, Sum = os.Sum(o => o.Amount) });


Он его преобразует в запрос вида:
exec sp_executesql N'SELECT TOP(1) [o].[AccountNo], SUM([o].[Amount]) AS [Sum]
FROM [PR_GLEntries] AS [o]
WHERE [o].[PostingDate] <= @__reportDate_0
GROUP BY [o].[AccountNo]
HAVING [o].[AccountNo] = @__acc_No_1',N'@__reportDate_0 datetime2(7),@__acc_No_1 nvarchar(4000)',@__reportDate_0='2018-07-20 00:00:00',@__acc_No_1=N'11000110'


Вот только у меня он падает на преобразовании из decimal(SQL) в decimal(Net).
А если пишу:
var accsSum = (from o in db.PR_GLEntries
                           where o.PostingDate <= reportDate
                           group o by o.AccountNo into os
                           select new AccountSumShort { AccountNo = os.Key, Sum = os.Sum(o => [b](double)[/b]o.Amount) });

То запрос выполняется, но начинается выборка по строчкам :(
20 июл 18, 12:15    [21588133]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация EF Core 2.0  [new]
Petro123
Member

Откуда: Загрузочный сектор Москвы (AutoPOI.ru)
Сообщений: 35700
gr,
ОРМ для CRUD учетного ПО.
Раньше или позже при аналитике вы упретесь в оверхед.
У вас задача - аналитика.
20 июл 18, 12:26    [21588234]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация EF Core 2.0  [new]
gr
Member

Откуда:
Сообщений: 29
Petro123,

Спасибо. Значит все таки буду смотреть Ado.net
20 июл 18, 14:03    [21588707]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация EF Core 2.0  [new]
Petro123
Member

Откуда: Загрузочный сектор Москвы (AutoPOI.ru)
Сообщений: 35700
gr
Petro123,

Спасибо. Значит все таки буду смотреть Ado.net

Задачу то мы не видим. Есть отчетники с прямым sql запросом внутри. Есть хранимки, вьюхи и т.д.
Сам смотри.
20 июл 18, 14:33    [21588891]     Ответить | Цитировать Сообщить модератору
 Re: Оптимизация EF Core 2.0  [new]
ЕвгенийВ
Member

Откуда: Москва
Сообщений: 4564
Обновись до ef core 2.1
https://docs.microsoft.com/ru-ru/ef/core/what-is-new/ef-core-2.1
25 июл 18, 12:05    [21600755]     Ответить | Цитировать Сообщить модератору
Все форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM Ответить