Гость
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / Как оптимизировать LINQ заявку / 23 сообщений из 23, страница 1 из 1
17.06.2016, 10:06
    #39257564
unsafe
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как оптимизировать LINQ заявку
Всем привет. Есть у нас метод. При таком подходе мы ведь выполняем излишнюю работу, вытаскивая вначале одного юзера со всеми его заказами. После чего уже в ифе считаем сумму всех его заказов. Возможно ли этот запрос сделать одной заявкой на LINQ?
Так же возникает вопрос, а что делать если придёться делать две заявки? Возможно ли их как то организовать что бы послать их одновременно, вместо того что бы делать два запроса к бд?
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
public CustomerAndOrdersPriceInfo GetCustomerAndOrdersPrice(int id)
{
    var customer = db.Customers
        .Include(c => c.Orders)
        .Where(c => c.CustomerId == id)
        .FirstOrDefault();

    if (customer != null)
    {
        CustomerAndOrdersPriceInfo record = new CustomerAndOrdersPriceInfo();
        record.FirstName = customer.FirstName;
        record.LastName = customer.LastName;
        record.Price = customer.Orders
            .GroupBy(o => o.CustomerId)
            .Select(c => c.Sum(o => o.Price)).
            .FirstOrDefault();

        return record;
    }

    return null;
}
...
Рейтинг: 0 / 0
17.06.2016, 17:16
    #39258036
Monochromatique
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как оптимизировать LINQ заявку
unsafeВсем привет. Есть у нас метод.

Метод просто агонь.



Код: c#
1.
2.
3.
4.
5.
6.
db.Customers.Select(x=> new { FirstName = x.FirstName ,LastName = x.LastName , _sum = orders.Sum(ord=>ord.price)}).toList().
Select(x=> new CustomerAndOrdersPriceInfo(){
FirstName = x.FirstName;
        LastName = x.LastName;
        Price = x._sum
} );



Заявка будет адна.
...
Рейтинг: 0 / 0
17.06.2016, 17:17
    #39258039
Monochromatique
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как оптимизировать LINQ заявку
MonochromatiqueunsafeВсем привет. Есть у нас метод.

Метод просто агонь.



Код: c#
1.
2.
3.
4.
5.
6.
db.Customers.Select(x=> new { FirstName = x.FirstName ,LastName = x.LastName , _sum = [color=red]x.[/color]orders.Sum(ord=>ord.price)}).toList().
Select(x=> new CustomerAndOrdersPriceInfo(){
FirstName = x.FirstName;
        LastName = x.LastName;
        Price = x._sum
} );



Заявка будет адна.
...
Рейтинг: 0 / 0
17.06.2016, 17:25
    #39258047
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как оптимизировать LINQ заявку
unsafe
Код: c#
1.
.Include(c => c.Orders)



Include — абсолютное зло. У нас я лично и саморучно линчую за подобное.
...
Рейтинг: 0 / 0
17.06.2016, 20:15
    #39258120
Monochromatique
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как оптимизировать LINQ заявку
hVosttunsafe
Код: c#
1.
.Include(c => c.Orders)



Include — абсолютное зло. У нас я лично и саморучно линчую за подобное.

А почему?
...
Рейтинг: 0 / 0
17.06.2016, 23:25
    #39258158
unsafe
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как оптимизировать LINQ заявку
Monochromatique, Разве всё настолько плохо с методом?
Проверил ваш метод, да, одной заявкой, но выглядит он ужасно.

hVostt, Чем так плох Include? Я стажируюсь, и у нас по умолчанию прокси и лайзилоадинг отключены.
...
Рейтинг: 0 / 0
18.06.2016, 08:18
    #39258182
Monochromatique
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как оптимизировать LINQ заявку
А ты эстет. Ну сделай так.

unsafe
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
public CustomerAndOrdersPriceInfo GetCustomerAndOrdersPrice(int id)
{
    var customerDTO = db.Customers
        .Where(c => c.CustomerId == id)
        .Select(c=> new {_customer = c, _sum = c.Orders.Sum(order=>order.price)})
        .FirstOrDefault();

    if (customer != null)
    {
        CustomerAndOrdersPriceInfo record = new CustomerAndOrdersPriceInfo();
        record.FirstName = customerDTO._customer.FirstName;
        record.LastName = customerDTO ._customer.LastName;
        record.Price = customerDTO._sum;

        return record;
    }

    return null;
}
...
Рейтинг: 0 / 0
18.06.2016, 08:21
    #39258183
Monochromatique
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как оптимизировать LINQ заявку
И я бы беспокоился не об одной "заявке" LINQ, а об этом куске:

Код: c#
1.
2.
3.
4.
record.Price = customer.Orders
            .GroupBy(o => o.CustomerId)
            .Select(c => c.Sum(o => o.Price)).
            .FirstOrDefault();



Человек, который такое пишет - опасен.
...
Рейтинг: 0 / 0
18.06.2016, 13:14
    #39258248
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как оптимизировать LINQ заявку
MonochromatiqueА почему?

Как почему? Потому что протаскивает в прикладуху подробности реализации слоя ORM, надо постоянно помнить о том, что надо включить в запрос эту инструкцию, или ты шишь получишь, надо понимать, что если ты делаешь Include коллекции, то будет извлечена вся коллекция (а это может быть мягко говоря, дохера), надо осознавать, что у Include свойства могут быть ещё вложенные свойства, которые надо вытащить, зачастую всего из-за одного какого-то поля. И к тому же это всё прибивает гвоздями к EF во всём проекте.


unsafehVostt, Чем так плох Include? Я стажируюсь, и у нас по умолчанию прокси и лайзилоадинг отключены.

Ну отключены и отключены. Используйте проекции.
...
Рейтинг: 0 / 0
19.06.2016, 13:29
    #39258442
unsafe
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как оптимизировать LINQ заявку
hVostt, Поэкспериментировал, остановился на вот такой вот финальной версии:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
public CustomerAndOrdersPriceInfo GetCustomerAndOrdersPrice(int id)
{
    return db.Customers
        .AsNoTracking()
        .Where(customer => customer.CustomerId == 1)
        .Select(customer => new CustomerAndOrdersPriceInfo
        {
            FirstName = customer.FirstName,
            LastName = customer.LastName,
            Price = customer.Orders.Sum(order => order.Price)
        })
        .FirstOrDefault();
}



Оцените пожалуйста.
...
Рейтинг: 0 / 0
19.06.2016, 16:46
    #39258475
Алексей К
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как оптимизировать LINQ заявку
unsafeОцените пожалуйста. AsNoTracking в данном случае ничего не даёт. Лучше убрать.
...
Рейтинг: 0 / 0
19.06.2016, 18:04
    #39258503
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как оптимизировать LINQ заявку
unsafe,

гуд. по поводу AsNoTracking присоединяюсь к Алексей К
...
Рейтинг: 0 / 0
20.06.2016, 06:58
    #39258619
Nechto
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как оптимизировать LINQ заявку
hVosttunsafe
Код: c#
1.
.Include(c => c.Orders)



Include — абсолютное зло. У нас я лично и саморучно линчую за подобное.

А если к примеру без условия .Where(c => c.CustomerId == id). Include("Customer") тоже зло?
...
Рейтинг: 0 / 0
20.06.2016, 07:19
    #39258625
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как оптимизировать LINQ заявку
NechtoА если к примеру без условия .Where(c => c.CustomerId == id). Include("Customer") тоже зло?

В любом случае зло. Этот Include добавлен для удовлетворения потребностей в создании учебных примеров. На практике же оно крайне вредно.
...
Рейтинг: 0 / 0
20.06.2016, 07:23
    #39258626
Nechto
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как оптимизировать LINQ заявку
hVosttNechtoА если к примеру без условия .Where(c => c.CustomerId == id). Include("Customer") тоже зло?

В любом случае зло. Этот Include добавлен для удовлетворения потребностей в создании учебных примеров. На практике же оно крайне вредно.

Блин. А я всегда использовал include. А как тогда быть? Справочники выносить в отдельный запрос что-ли?
...
Рейтинг: 0 / 0
20.06.2016, 07:26
    #39258627
Nechto
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как оптимизировать LINQ заявку
include это тот же left join
...
Рейтинг: 0 / 0
20.06.2016, 11:07
    #39258709
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как оптимизировать LINQ заявку
NechtoБлин. А я всегда использовал include. А как тогда быть? Справочники выносить в отдельный запрос что-ли?

Решение: AutoMapper + DTO. Кстати, потом ты уже по-другому просто не захочешь.
...
Рейтинг: 0 / 0
20.06.2016, 13:31
    #39258835
unsafe
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как оптимизировать LINQ заявку
hVostt, Зачем убирать AsNotracking? Разве по умолчанию данные не будут загружены в контекст? Если объекты вычитанные с помощью Entity Framework, не будут изменены и не будут участвовать в модификациях других объектов, нужно вызывать AsNoTracking() для коллекции. Или я неправильно понял .

Не хотелось бы создавать новую тему, к тому же вопрос по этой же теме . Встрял в тупик с одной функцией. Целью является создание пагинация.
Есть у меня дженерик класс:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
    public class PageInfo<T> where T : class
    {
        public IEnumerable<T> Items { get; set; }
        public int PageNumber { get; set; }
        public int PageSize { get; set; }
        public int TotalItems { get; set; }
        public int TotalPages
        {
            get { return (int)Math.Ceiling((decimal)TotalItems / PageSize); }
        }
    }


У функции ни как не могу сообразить как написать селект, что бы получить одновременно и список с элементами, и общее их кол-во. Так же вопрос насчёт .Skip(() => startFromPage).Take(() => pageSize). Ментор сказал что мы не сильно выигрываем от такой оптимизации, а читаемость кода при этом уменьшается, мол лучше просто использовать число. Функция:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
        public PageInfo<CustomerAndOrdersPriceInfo> GetCustomersWithOrdersPrice(int page, int pageSize)
        {
            int startFromPage = (page - 1) * pageSize;
            
            return db.Customers
                .AsNoTracking()
                .Select(customer => new PageInfo<CustomerAndOrdersPriceInfo>
                {
                    //???
                })
                .OrderBy(customer => customer.FirstName)
                .Skip(() => startFromPage)
                .Take(() => pageSize)
                .ToList();
        }


Где класс CustomerAndOrdersPriceInfo у нас:
Код: c#
1.
2.
3.
4.
5.
6.
    public class CustomerAndOrdersPriceInfo
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public decimal Price { get; set; }        
    }

...
Рейтинг: 0 / 0
20.06.2016, 17:06
    #39259051
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как оптимизировать LINQ заявку
unsafehVostt, Зачем убирать AsNotracking? Разве по умолчанию данные не будут загружены в контекст?

Нет, не будут, так как ты делаешь проекцию. EF выберет только те поля, которые ты сам указал.


unsafeчто бы получить одновременно и список с элементами, и общее их кол-во

не надо


unsafeМентор сказал что мы не сильно выигрываем от такой оптимизации

я бы даже сказал, мы крупно проигрываем

забери нужный набор данных и отдельно извлеки общее количество, не надо мудрить.
...
Рейтинг: 0 / 0
21.06.2016, 12:46
    #39259557
unsafe
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как оптимизировать LINQ заявку
hVostt, При любом наличии Select в заявке отбрасывать AsNoTracking??
А что по поводу статьи ? Если учесть что Вы уже отбросили варинт с использованием лямбды в Skip и Take, насколько правдиво то что написано. Или где можно почтить про оптимизации EF
...
Рейтинг: 0 / 0
22.06.2016, 07:41
    #39260078
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как оптимизировать LINQ заявку
unsafehVostt, При любом наличии Select в заявке отбрасывать AsNoTracking??

При наличии Select с проекцией: p => new { p.A, p.B }.

unsafeИли где можно почтить про оптимизации EF

Большая часть информации по оптимизации EF настолько очевидна, что вам не требуется читать об этом в каких-то блогах.

Самая мощнейшая оптимизация в EF, это проекции. Они ускоряют работу с БД до уровня, приближённого к нативным интерфейсам (ADO.NET) и по скорости держатся рядом с ультракомпактными и быстрыми ORM, как Dapper.

Вот и всё, что нужно знать для начала. AsNoTracking это тоже костыль, который нафиг не упал, у нас в одном довольно большом проекте ни одного AsNoTracking  — и всё работает очень быстро. Даже при всём желании нам добавить его просто тупо некуда, где мы только читаем данные, используются проекции. Где мы пишем данные, используется трекинг для эффективных запросов на запись.

Нафиг он вообще нужен, кроме как для учебных лабораторных студенческих поделок или для создания ложного ощущения безопасной оптимизации — я не знаю. Советую не забивать голову трекингами и переходить к задачам бизнеса. А оптизимацией заниматься только тогда, когда это потребуется, не раньше.
...
Рейтинг: 0 / 0
01.07.2016, 07:16
    #39266011
Nechto
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как оптимизировать LINQ заявку
hVosttNechtoБлин. А я всегда использовал include. А как тогда быть? Справочники выносить в отдельный запрос что-ли?

Решение: AutoMapper + DTO. Кстати, потом ты уже по-другому просто не захочешь.

Я так понимаю это дополнение к EF Code First? Или это вообще отдельный движок работы с базой данных?

...
Рейтинг: 0 / 0
01.07.2016, 13:08
    #39266318
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как оптимизировать LINQ заявку
NechtoЯ так понимаю это дополнение к EF Code First?

Нет, это не дополнение к EF и никак с ним напрямую не связано. AutoMapper это грубо говоря средство для копирования значений свойств экземпляра одного класса в экземпляр другого класса. Особенность этой библиотеки в том, что она умеет делать проекции для LINQ, которые «понимает» EF. Т.е. можно определить DTO класс, в который проецируются сущности EF, при этом строится эффективный SQL-запрос, которым можно управлять в конфигурации отражения AutoMapper.

По большему счёту это даёт возможность практически забыть о голом SQL в подавляющем большинстве случаев, и при этом не потеря в возможности строить эффективные запросы. Остаются только тяжёлые случаи для оптимизаций, которые решаются отражением SQL VIEW на сущность EF, и оставшиеся совсем редкие случаи — это вызовы функций и процедур из SQL, но мы научились полностью обходиться без них. Мы находим элегантные быстрые решения без привлечения SQL там, где многие корифеи с пеной у рта нам доказывали, что мы без SQL утрёмся.
...
Рейтинг: 0 / 0
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / Как оптимизировать LINQ заявку / 23 сообщений из 23, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]