Если есть Unit Of Work
с сущностями типа Clients Orders
которые имеют например бизнес-логику Cliens.FindByInn(...)
то я просто могу передать этот uow и аыполнить операциями.
но если у нас dbcontext то Clients это просто IQueriable
и если инкапсулировать Clients, то у меня нет доступа к ордерс и наоборот.
И, например, чтобы сортирнуть по произвольному полю, мне придется городить экспрешн.
Неужели, Рич Хикки был прав и надо быть проще?
Здравствуйте, varenikAA, Вы писали:
AA>Я в тупике.
AA>Если есть Unit Of Work AA>с сущностями типа Clients Orders AA>которые имеют например бизнес-логику Cliens.FindByInn(...) AA>то я просто могу передать этот uow и аыполнить операциями. AA>но если у нас dbcontext то Clients это просто IQueriable AA>и если инкапсулировать Clients, то у меня нет доступа к ордерс и наоборот. AA>И, например, чтобы сортирнуть по произвольному полю, мне придется городить экспрешн. AA>Неужели, Рич Хикки был прав и надо быть проще?
Пиши проще, ищи повторения и закономерности. Писать по патернам часто дикий ненужный overhead.
И что значит есть Unit Of Work с сущностями? UoW это в основином контекст транзакции. Или ты попутал его с репозиторием?
Здравствуйте, varenikAA, Вы писали:
AA>Я в тупике.
AA>Если есть Unit Of Work AA>с сущностями типа Clients Orders AA>которые имеют например бизнес-логику Cliens.FindByInn(...) AA>то я просто могу передать этот uow и аыполнить операциями. AA>но если у нас dbcontext то Clients это просто IQueriable AA>и если инкапсулировать Clients, то у меня нет доступа к ордерс и наоборот. AA>И, например, чтобы сортирнуть по произвольному полю, мне придется городить экспрешн.
Это всё глупые самоограничения.
AA>Неужели, Рич Хикки был прав и надо быть проще?
Зачем сущности воплощать в коде, если они тебе не удобны? Создавай их отражения под нужным тебе углом — в простейшем случае это будут просто структуры с данными, где у тебя сразу есть вся нужная тебе информация и они с ходу поддерживают нужные тебе операции.
И не надо писать код наизнанку: наружу должен торчать твой код, а не чужой. Не нужно светить IQueryable<Client>, свети ClientCollection — твой класс, который поддерживает только нужные операции и ничего больше: доступ к дополнительным полям в элементах коллекции, сортировки как надо и прочее. Если так сделать, ты всегда будешь сходу понимать что этот код делает везде, где он используется; если будет баг, он будет исправлен внутри реализации этого класса, а не везде где он используется; и вообще это код будет редко меняться там, где он используется.
Пример:
ClientInfo — содержит все нужные данные от конкретного клиента и его заказов, и методы, которые могут обновить эту информацию как надо (добавить заказ, например).
ClientInfo.FindByInn или похожий метод поиска — выдаёт экземпляр или коллекцию ClientInfo (ClientInfoColecction).
ClientInfoCollection — умеет всё, что от этого класса нужно — сортировку, фильтрацию и тому подобное.
Это обычный ООП: объекты с полями и методами. В своей реализации твои классы дёргают EF с его "сущностями" самым оптимальным образом, но наружу у них торчит только твой код. Это сложно в смысле объёма кода, но проще в смысле количества сущностей, которыми тебе приходится оперировать: эти классы ты сам придумал, их конечное число, они делают только то, что нужно; это не солянка из кусков всяких фреймворков. Все детали от EF и прочего тут внутри реализации твоих классов, именно так их надо использовать.
Здравствуйте, varenikAA, Вы писали:
AA>Я в тупике.
AA>Если есть Unit Of Work AA>с сущностями типа Clients Orders AA>которые имеют например бизнес-логику Cliens.FindByInn(...) AA>то я просто могу передать этот uow и аыполнить операциями. AA>но если у нас dbcontext то Clients это просто IQueriable AA>и если инкапсулировать Clients, то у меня нет доступа к ордерс и наоборот.
Непонятно, почему нет доступа к ордерс?
Можно же сегментировать dbContext — например, иметь
AA>И, например, чтобы сортирнуть по произвольному полю, мне придется городить экспрешн.
Это как?
Берём и сортируем:
public static OrderInfo? FirstOrder(this IOrderManagement om, int clientId)
{
return (from o in om.Orders where o.ClientID == clientId order by o.OrderDate desc select o).FirstOrDefault();
}
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
AA>>И, например, чтобы сортирнуть по произвольному полю, мне придется городить экспрешн. S>Это как? S>Берём и сортируем: S>
S>public static OrderInfo? FirstOrder(this IOrderManagement om, int clientId)
S>{
S> return (from o in om.Orders where o.ClientID == clientId order by o.OrderDate desc select o).FirstOrDefault();
S>}
S>
А зачем вообще этот IOrderManagement, если можно просто client.Orders?
Здравствуйте, varenikAA, Вы писали: AA> public List<Client> Page(int page, int size, string orderBy, string partName) // <- Вот здесь требуется сортировка по произвольному полю. OrderBy требуется Expression AA> { AA> return db.Clients.Where(c => c.FullName.ToLower().Contains(partName)) AA> .OrderBy(x => x.GetType().GetProperty(orderBy).GetValue(x, null)) AA> .Skip(page * size).Take(size).ToList(); AA> } AA> } AA>[/cs]
А зачем так делать? Почему вы не хотите просто выставить наружу IQueryable<Client>?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Sinclair, Вы писали:
S>Здравствуйте, varenikAA, Вы писали: AA>> public List<Client> Page(int page, int size, string orderBy, string partName) // <- Вот здесь требуется сортировка по произвольному полю. OrderBy требуется Expression AA>> { AA>> return db.Clients.Where(c => c.FullName.ToLower().Contains(partName)) AA>> .OrderBy(x => x.GetType().GetProperty(orderBy).GetValue(x, null)) AA>> .Skip(page * size).Take(size).ToList(); AA>> } AA>> } AA>>[/cs] S>А зачем так делать? Почему вы не хотите просто выставить наружу IQueryable<Client>?
В одном из ответов дали хороший совет, в реализации должен быть только нужный функционал.
Тут дело в другом, если использовать Ado или микро-ОРМ то я просто сортирую средствами СУБД,
а в случае EF либо через выражение либо через свитч(что еще хуже так как придется менять реализацию при добавлении новой сортировки).
в том же clojure предусмотрены keywords, но там динамика. в C# такое не приветствуется. Статика она такая.