powered by simpleCommunicator - 2.0.33     © 2025 Programmizd 02
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / Передача лямбды в репозиторий. Где ошибка?
25 сообщений из 130, страница 1 из 6
Передача лямбды в репозиторий. Где ошибка?
    #39798485
Maksimka-27
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Разбираю Pro Entity Framework Core 2 for ASP.NET Core MVC замечательного автора Adam Freeman.

Строится модель, например:
public class Product
{
public long Id { get; set; }
public string Name { get; set; }
[Column(TypeName = "decimal(18, 2)")]
public decimal PurchasePrice { get; set; }
}

Строим класс репозитория (объявление контекста и интерфейса- опускаю):

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
public class DataRepository : IRepository
    {
        
        private DataContext context;

        public DataRepository(DataContext ctx) => context = ctx;

       public IEnumerable<Product> ProductsChoose(Func<Product, bool> func)
          {
            IEnumerable<Product> p = context.Products
                    .Where(func)
                    .ToList();    
            return p;   
           }



В контроллере идет вызов:
Код: c#
1.
     IEnumerable<Product> p = repository.ProductsChoose(x => x.RetailPrice < 100);



При этом формируется SQL:
Код: sql
1.
2.
3.
Executed DbCommand (31ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT [p].[Id], [p].[CategoryId], [p].[Name], [p].[PurchasePrice], [p].[RetailPrice]
FROM [Products] AS [p]



Но если я переписываю репозиторий ():

Код: c#
1.
2.
3.
4.
5.
6.
public IEnumerable<Product> ProductsChoose(Func<Product, bool> func)
          {
            IEnumerable<Product> p = context.Products
                    .Where(x => x.RetailPrice < 100)
                    .ToList();    
            return p;   }



[то получаю вполне ожидаемый код, который ведет отбор на сервере базы данных:
Код: sql
1.
2.
3.
SELECT [x].[Id], [x].[CategoryId], [x].[Name], [x].[PurchasePrice], [x].[RetailPrice]
FROM [Products] AS [x]
WHERE [x].[RetailPrice] < 100.0



При этом результаты вывода - одинаковые.
Почему передача лямбды в репозиторий приводит к фильтрации строк на стороне EF а не SQL?
Где я ошибаюсь?
...
Рейтинг: 0 / 0
Передача лямбды в репозиторий. Где ошибка?
    #39798514
L.Otujktd
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Maksimka-27,
Скорее всего проблема в отложенном выполнении, реальное преобразование в запрос происходит на момент вычисления всей цепочки, ваш внешний func не может заинжектиться корректно, что логично. Надо смотреть в доке как разбирается Linq
...
Рейтинг: 0 / 0
Передача лямбды в репозиторий. Где ошибка?
    #39798521
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
пробуй
Код: c#
1.
ProductsChoose(Expression<Func<Product, bool>> func)
...
Рейтинг: 0 / 0
Передача лямбды в репозиторий. Где ошибка?
    #39798555
Maksimka-27
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Shocker.Pro,

Помогло, Спасибо!!!!
...
Рейтинг: 0 / 0
Передача лямбды в репозиторий. Где ошибка?
    #39798594
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Maksimka-27Разбираю Pro Entity Framework Core 2 for ASP.NET Core MVC замечательного автора Adam Freeman.хмм...
А MS со своим кодом ниже в пику ему делает свои справки и демки?
dotnet ef dbcontext scaffold xxxxxxxxxx
И получаем вместо репозитория класс XXXContext.cs
?
...
Рейтинг: 0 / 0
Передача лямбды в репозиторий. Где ошибка?
    #39798600
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Фримен упирает на модульное тестирование, поэтому интерфейс для репозитория в примере - вполне в его стиле.
...
Рейтинг: 0 / 0
Передача лямбды в репозиторий. Где ошибка?
    #39798609
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shocker.Pro,
Спс.
...
Рейтинг: 0 / 0
Передача лямбды в репозиторий. Где ошибка?
    #39798635
L.Otujktd
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Shocker.Proпробуй
Код: c#
1.
ProductsChoose(Expression<Func<Product, bool>> func)


+1
...
Рейтинг: 0 / 0
Передача лямбды в репозиторий. Где ошибка?
    #39798685
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Maksimka-27
Код: c#
1.
IEnumerable<Product>



IQueryable
...
Рейтинг: 0 / 0
Передача лямбды в репозиторий. Где ошибка?
    #39798698
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttMaksimka-27
Код: c#
1.
IEnumerable<Product>




IQueryableтогда
.ToList();
будет лишним?
...
Рейтинг: 0 / 0
Передача лямбды в репозиторий. Где ошибка?
    #39798768
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Petro123.ToList();
будет лишним?

делать ToList() и возвращать IEnumerable сродни тому, как плюнуть в лицо :)

хотя бы ICollection, хотя желательно IReadOnlyCollection

касательно озвученной проблемы, правильно решается с помощью паттерна спецификаций, например:

https://enterprisecraftsmanship.com/2016/02/08/specification-pattern-c-implementation/
...
Рейтинг: 0 / 0
Передача лямбды в репозиторий. Где ошибка?
    #39798817
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttделать ToList() и возвращать IEnumerable сродни тому, как плюнуть в лицо :))))
...
Рейтинг: 0 / 0
Передача лямбды в репозиторий. Где ошибка?
    #39798823
Фотография Shocker.Pro
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttделать ToList() и возвращать IEnumerable сродни тому, как плюнуть в лицо :)Кстати, слышал как-то формулу - параметр метода должен быть максимально абстрактного типа, результат - максимально конкретного. Скажи, гуру, ты согласен с этой формулой?

То есть, в данном случае, вернуть прямо таки List<>. Если потребителю нужен ICollection - он сам выполнит приведение. А может ему понадобится непосредственно функционал листа.
...
Рейтинг: 0 / 0
Передача лямбды в репозиторий. Где ошибка?
    #39798827
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shocker.ProЕсли потребителю нужен ICollection - он сам выполнит приведение.с этим не согласен.
Возвращать нужно то что просят выше. Чтобы 200 вызовов не приводить и кода не добавлять.
...
Рейтинг: 0 / 0
Передача лямбды в репозиторий. Где ошибка?
    #39799068
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Shocker.ProКстати, слышал как-то формулу - параметр метода должен быть максимально абстрактного типа, результат - максимально конкретного. Скажи, гуру, ты согласен с этой формулой?

Главное не путать абстракцию с семантикой.

IEnumerable -- это бесконечная последовательность, в качестве которой может выступать как коллекция, так и генератор, поэтому он не является абстракцией коллекции.

самая максимальная абстракция коллекции в C# это IReadOnlyCollection.

Shocker.ProТо есть, в данном случае, вернуть прямо таки List<>.

Ни в коем случае. List это реализация. Вообще самые злостные крайности джунов это возвращать IEnumerable, или List. Ругаю очень за такое.

Shocker.ProЕсли потребителю нужен ICollection - он сам выполнит приведение. А может ему понадобится непосредственно функционал листа.

Я говорю конкретно про контракты.
...
Рейтинг: 0 / 0
Передача лямбды в репозиторий. Где ошибка?
    #39799129
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttНи в коем случае. List это реализация. Вообще самые злостные крайности джунов это возвращать IEnumerable, или List. Ругаю очень за такое.не понял. Я налево и направо возвращаю.
А что делать, если наверху правят эту коллекцию?
...
Рейтинг: 0 / 0
Передача лямбды в репозиторий. Где ошибка?
    #39799178
ViPRos
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Petro123hVosttНи в коем случае. List это реализация. Вообще самые злостные крайности джунов это возвращать IEnumerable, или List. Ругаю очень за такое.не понял. Я налево и направо возвращаю.
А что делать, если наверху правят эту коллекцию?
надо вернуть метаданные - адрес памяти, длина блока памяти
а там пусть как хотят так и интерпретируют
а то всякие там коллекции и т.д. не кошерны
...
Рейтинг: 0 / 0
Передача лямбды в репозиторий. Где ошибка?
    #39799188
Фотография Petro123
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ViPRosнадо вернуть метаданные - адрес памяти, длина блока памятив Net есть Pointer или *p
?
...
Рейтинг: 0 / 0
Передача лямбды в репозиторий. Где ошибка?
    #39799231
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Petro123не понял. Я налево и направо возвращаю.
А что делать, если наверху правят эту коллекцию?

если коллекция может правиться, то ICollection.
если к этому нужен индексированный доступ, то IList.

контракты должны быть максимально абстрактными, но не нарушать семантику.
а то можно вообще везде object возвращать, чё мелочиться-то? :)
...
Рейтинг: 0 / 0
Передача лямбды в репозиторий. Где ошибка?
    #39799280
stenford
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttIQueryable
руки отрубать за такое надо. Логика запросов расползется по всем слоям убив поддерживаемость и производительность
...
Рейтинг: 0 / 0
Передача лямбды в репозиторий. Где ошибка?
    #39799290
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stenfordhVosttIQueryable
руки отрубать за такое надо. Логика запросов расползется по всем слоям убив поддерживаемость и производительность

серьёзно? за много лет мне ещё никто не доказал и не показал, что там "убивается" в поддержке и производительности

IQueryable это абстрактный контракт слоя работы с данными. ни чем не отличается от +100500 других костылей и способов, просто у отдельных людей откуда-то возникает панический страх, который они не могут ни понять, ни объяснять.

работай со слоем доступа к данным из слоя логики, не тащи на клиентский слой, в чём проблемы?

это прям когнитивный диссонанс. видишь как человек боится юзать IQueryable, потом смотришь а он там прокидывает IEnumerable или вообще List -- дабл фейспалм.
...
Рейтинг: 0 / 0
Передача лямбды в репозиторий. Где ошибка?
    #39799315
stenford
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hVosttсерьёзно? за много лет мне ещё никто не доказал и не показал, что там "убивается" в поддержке и производительности

IQueryable это абстрактный контракт слоя работы с данными. ни чем не отличается от +100500 других костылей и способов, просто у отдельных людей откуда-то возникает панический страх, который они не могут ни понять, ни объяснять.

работай со слоем доступа к данным из слоя логики, не тащи на клиентский слой, в чём проблемы?

это прям когнитивный диссонанс. видишь как человек боится юзать IQueryable, потом смотришь а он там прокидывает IEnumerable или вообще List -- дабл фейспалм.
то, что ты чего-то там в своей жизни не видел не влияет на то, как эти вещи работают, если у тебя создан репозиторий - то логика запросов должна содержаться в нем по указанным выше причинам, в простых случаях он не нужен и никто не мешает работать с базой из слоя логики, а кашу и репозитория и логики запросов в нескольких слоях лепят только студенты на первых годах своей работы пока не поднаберутся опыта
...
Рейтинг: 0 / 0
Передача лямбды в репозиторий. Где ошибка?
    #39799451
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stenfordто, что ты чего-то там в своей жизни не видел не влияет на то, как эти вещи работают, если у тебя создан репозиторий - то логика запросов должна содержаться в нем по указанным выше причинам, в простых случаях он не нужен и никто не мешает работать с базой из слоя логики, а кашу и репозитория и логики запросов в нескольких слоях лепят только студенты на первых годах своей работы пока не поднаберутся опыта

абосолютно ни о чём. IQueryable это абстракция. ни чем не хуже любых созданных вами кривых поделок, и не надо тут залечивать про кашу, не умеете -- не варите.

про репозитории вида god queries object уже писалось не раз, обсуждалось. то, что вы слыхом про это не слыхивали, проблемы только ваши.
...
Рейтинг: 0 / 0
Передача лямбды в репозиторий. Где ошибка?
    #39799452
Фотография hVostt
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stenfordна первых годах своей работы пока не поднаберутся опыта

как я вижу, многим и десятки лет опыта ничего не дают. как лепят свои унылые поделки, которые освоили на студенческих примерах, так и продолжают лепить до посинения.
...
Рейтинг: 0 / 0
Передача лямбды в репозиторий. Где ошибка?
    #39800739
love_bach
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Maksimka-27Разбираю Pro Entity Framework Core 2 for ASP.NET Core MVC замечательного автора Adam Freeman.

Строится модель, например:
public class Product
{
public long Id { get; set; }
public string Name { get; set; }
[Column(TypeName = "decimal(18, 2)")]
public decimal PurchasePrice { get; set; }
}

Строим класс репозитория (объявление контекста и интерфейса- опускаю):

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
public class DataRepository : IRepository
    {
        
        private DataContext context;

        public DataRepository(DataContext ctx) => context = ctx;

       public IEnumerable<Product> ProductsChoose(Func<Product, bool> func)
          {
            IEnumerable<Product> p = context.Products
                    .Where(func)
                    .ToList();    
            return p;   
           }



В контроллере идет вызов:
Код: c#
1.
     IEnumerable<Product> p = repository.ProductsChoose(x => x.RetailPrice < 100);



При этом формируется SQL:
Код: sql
1.
2.
3.
Executed DbCommand (31ms) [Parameters=[], CommandType='Text', CommandTimeout='30']
SELECT [p].[Id], [p].[CategoryId], [p].[Name], [p].[PurchasePrice], [p].[RetailPrice]
FROM [Products] AS [p]



Но если я переписываю репозиторий ():

Код: c#
1.
2.
3.
4.
5.
6.
public IEnumerable<Product> ProductsChoose(Func<Product, bool> func)
          {
            IEnumerable<Product> p = context.Products
                    .Where(x => x.RetailPrice < 100)
                    .ToList();    
            return p;   }



[то получаю вполне ожидаемый код, который ведет отбор на сервере базы данных:
Код: sql
1.
2.
3.
SELECT [x].[Id], [x].[CategoryId], [x].[Name], [x].[PurchasePrice], [x].[RetailPrice]
FROM [Products] AS [x]
WHERE [x].[RetailPrice] < 100.0



При этом результаты вывода - одинаковые.
Почему передача лямбды в репозиторий приводит к фильтрации строк на стороне EF а не SQL?
Где я ошибаюсь?

а нафига вообще такой репозиторий?
...
Рейтинг: 0 / 0
25 сообщений из 130, страница 1 из 6
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / Передача лямбды в репозиторий. Где ошибка?
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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