Рассмотрим, например, FULL JOIN. В библиотеке LinqToDb вижу, что добавили эту функцию, но в оригинальном ответе я ссылался на Linq to SQL где ничего подобного нет.
Допустим мне нужен LEFT JOIN. С билдером синтаксического дерева, я вызываю функцию “LeftJoin”. В случае LINQ я лезу в гугл и нахожу, что именно вот такая последовательность вызовов будет интерпретирована как Left Join:
join p in products on c.Category equals p.Category into ps
from p in ps.DefaultIfEmpty()
Идея в том, что нет однозначного отображения из LINQ в SQL
Если вы имеет в виду Linq to SQL то это не совсем полноценный аналог, поскольку в нем не строится в явном виде синтаксическое дерево SQL запросов. Linq пытается преобразовать выражения на языке C# в SQL запрос, что не дает полноценного контроля над результатом.
По поводу ReadOnly и IImmutableList полностью согласен, я их всегда использую в подобных методах, тут я просто не хотел отвлекать внимание и лишь указать на тот факт, что метод возвращает ссылку на список расположенный в памяти.
IEnumerable(int) на входе, дает нам возможность без лишних буферов в памяти использовать LINQ
Пример “от балды”:
ReadEntities(items.Where(i=> i > 1000))
Что По поводу типа результата List<Entitiy>, то в случае чтения из базы данных я соглашусь что ленивое чтение было бы предпочтительнее (хотя есть нюансы, о которых чуть позже), но в случае с обычным REST Api “ленивое” чтение уже не выйдет. Теперь про нюансы с ленивым чтением — в наши дни, думаю, многие уже поняли важность неблокирующего кода, потому в реальности контракт выглядел бы так:
Спасибо за пример, если честно, не знал что существует отдельная реализация int? Max(this IEnumerable<int?> source) Но по сути, проверка на пустоту все же есть, только она скрыта в реализации Max(this IEnumarable<int?> source)
По поводу проверки на null, статья все же была не об этом. Проверять или не проверять на нулл это тема отельного большого холивара. По моему мнению, возможность передачи аргументов со значением null должна быть как-то оговорена в контракте метода, но к сожалению, пока в C# нет встроенных возможностей указать необходимость наличия значения у аргументов с ссылочными типами – ждем C#8. Сейчас можно использовать атрибуты [Null] [NotNull] и какой-нибудь статический анализатор и в любом случае ситуация с null должна быть оговорена в документации к методу.
По поводу вашей реализации GetSum – она вполне может применяться, но она не менее громоздкая. К тому же у вас введены две изменяемые переменные, что совершенно не критично, но идет в разрез с современными тенденциями в программировании (это я про ФП)
(можем получить исключение Sequence contains no elements)
Не имея исходного кода сторонней библиотеки, сложно сказать насколько оправданно использование перечисления вместо коллекции, но допустим, что оправданно.
Назначение у DefaultIsEmpty() несколько другое, этот метод возвращает перечислитель с одним дефолтным элементом в том случае если исходный перечислитель не содержит элементов. Можно применить для симуляции поведения LEFT OUTTER JOIN, но этот метод никак не применим если надо проверить наличие элементов в исходном перечислителе.
В статье приравниваются понятия аутентификации на основе кук и на основе сессий. Но ничто не мешает положить тот же токен в куку и не создавать сессии на сервере.
Я имел в виду, что с архитектурной точки зрения основа Ангуляра не привязана к отдельным его модулям и он не принуждает их использовать. Ничто не мешает делать запросы через, например, jQuery или fetch.
C претензиями к Roter, HttpClient и Forms я соглашусь, но к плюсам ангуляра можно отнести относительную модульность и как результат возможность не использовать эти модули, что мы благополучно и делаем на нашем проекте — у нас свой роутер, свой http клиент и свои Dynamic Forms. Причины почему, так вышло были разные и я не агитирую поступать так же, но, тем не менее, возможность заменить не базовые модули ангуляра есть, если стандартные чем-то не устраивают.
join p in products on c.Category equals p.Category into ps
from p in ps.DefaultIfEmpty()
Идея в том, что нет однозначного отображения из LINQ в SQL
да, но только для последнего итератора, в котором что бы получить первый исходящий элемент (<10) нужно перебрать 91 входящий элемент (>= 10).
IEnumerable(int) на входе, дает нам возможность без лишних буферов в памяти использовать LINQ
Пример “от балды”:
Что По поводу типа результата List<Entitiy>, то в случае чтения из базы данных я соглашусь что ленивое чтение было бы предпочтительнее (хотя есть нюансы, о которых чуть позже), но в случае с обычным REST Api “ленивое” чтение уже не выйдет. Теперь про нюансы с ленивым чтением — в наши дни, думаю, многие уже поняли важность неблокирующего кода, потому в реальности контракт выглядел бы так:
но тут ленивое чтение не особо то выходит, хотя можно было бы сделать неблокирующий код с ленивым чтением вот таким образом:
но все же мой идеал контракта это:
Ждем C#8 :)
По поводу вашей реализации GetSum – она вполне может применяться, но она не менее громоздкая. К тому же у вас введены две изменяемые переменные, что совершенно не критично, но идет в разрез с современными тенденциями в программировании (это я про ФП)
Вот вполне реалистичный пример, где проверка на пустоту имеет смысл:
(можем получить исключение Sequence contains no elements)
Не имея исходного кода сторонней библиотеки, сложно сказать насколько оправданно использование перечисления вместо коллекции, но допустим, что оправданно.
Если не проверять entityIds на пустоту, то может возникнуть ситуация, когда выполняется ненужный ресурсоемкий запрос.
2. Sum null не вернет
В статье приравниваются понятия аутентификации на основе кук и на основе сессий. Но ничто не мешает положить тот же токен в куку и не создавать сессии на сервере.