Entity Framework Core vs Business Logic
От: varenikAA  
Дата: 04.09.20 12:25
Оценка:
Я в тупике.

Если есть Unit Of Work
с сущностями типа Clients Orders
которые имеют например бизнес-логику Cliens.FindByInn(...)
то я просто могу передать этот uow и аыполнить операциями.
но если у нас dbcontext то Clients это просто IQueriable
и если инкапсулировать Clients, то у меня нет доступа к ордерс и наоборот.
И, например, чтобы сортирнуть по произвольному полю, мне придется городить экспрешн.
Неужели, Рич Хикки был прав и надо быть проще?
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re: Entity Framework Core vs Business Logic
От: Danchik Украина  
Дата: 04.09.20 13:16
Оценка:
Здравствуйте, 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 это в основином контекст транзакции. Или ты попутал его с репозиторием?
Re: Entity Framework Core vs Business Logic
От: bnk СССР http://unmanagedvisio.com/
Дата: 04.09.20 14:03
Оценка: :)
Здравствуйте, varenikAA, Вы писали:

AA> Cliens.FindByInn(...)


Найти по трактиру?! Похоже что-то интересное пишешь С другой стороны, сегодня пятница где еще искать народ
Re: Entity Framework Core vs Business Logic
От: Vladek Россия Github
Дата: 05.09.20 09:05
Оценка: 4 (1) :)
Здравствуйте, 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 и прочего тут внутри реализации твоих классов, именно так их надо использовать.

Бизнес-логика наружу, фреймворки внутри.
Re: Entity Framework Core vs Business Logic
От: Sinclair Россия https://github.com/evilguest/
Дата: 05.09.20 14:00
Оценка:
Здравствуйте, varenikAA, Вы писали:

AA>Я в тупике.


AA>Если есть Unit Of Work

AA>с сущностями типа Clients Orders
AA>которые имеют например бизнес-логику Cliens.FindByInn(...)
AA>то я просто могу передать этот uow и аыполнить операциями.
AA>но если у нас dbcontext то Clients это просто IQueriable
AA>и если инкапсулировать Clients, то у меня нет доступа к ордерс и наоборот.
Непонятно, почему нет доступа к ордерс?
Можно же сегментировать dbContext — например, иметь
IOrderManagement
{
  IQueryable<Client> Clients {get;}
  IQueryavle<Order> Orders {get;}
}

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();
}
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[2]: Entity Framework Core vs Business Logic
От: Ночной Смотрящий Россия  
Дата: 05.09.20 14:26
Оценка:
Здравствуйте, 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?
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[3]: Entity Framework Core vs Business Logic
От: Sinclair Россия https://github.com/evilguest/
Дата: 06.09.20 10:59
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:
НС>А зачем вообще этот IOrderManagement, если можно просто client.Orders?
Можно и так.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[2]: Entity Framework Core vs Business Logic
От: varenikAA  
Дата: 07.09.20 02:16
Оценка:
Здравствуйте, Sinclair, Вы писали:

AA>>И, например, чтобы сортирнуть по произвольному полю, мне придется городить экспрешн.

S>Это как?
    public class ClientService
    {
        private readonly ItAutoContext db;

        public ClientService(ItAutoContext context)
        {
            db = context;
        }

        public IEnumerable<Client> All()
        {
            return db.Clients.OrderBy(c => c.FullName);
        }

        public List<Client> Page(int page, int size, string orderBy, string partName) // <- Вот здесь требуется сортировка по произвольному полю. OrderBy требуется Expression
        {
            return db.Clients.Where(c => c.FullName.ToLower().Contains(partName))
                .OrderBy(x => x.GetType().GetProperty(orderBy).GetValue(x, null))
                .Skip(page * size).Take(size).ToList();
        }

        public Client FindByInn(string inn, string kpp = "")
        {
            return db.Clients.FirstOrDefault<Client>( c => c.Inn == inn && c.Kpp == kpp);
        }

        public int Count()
        {
            return db.Clients.Count();
        }

    }


В самописной реализации я сделал так(под капотом PetaPoco):

    public class Clients : DataQuery<Client>
    {
        private readonly Sql select;
        public Clients(IDatabase database) : base(database)
        {
            select = Sql.Builder.From("Client");
        }

        public override List<Client> All()
        {
            return Database.Fetch<Client>(select.Append(" order by FullName"));
        }

        public Page<Client> Page(long page, long size, string orderBy, string partName)
        {
            var sql = select;
            if (!string.IsNullOrWhiteSpace(partName))
                sql.Where("lower(FullName) like @0", "%" + partName.ToLowerInvariant() + "%");
            sql.OrderBy(orderBy);
            return Database.Page<Client>(page, size, sql);
        }

        public Client FindByInn(string inn, string kpp = "")
        {
            return Database.FirstOrDefault<Client>(select.Where(" inn = @0 and kpp = @1").SQL, inn, kpp);
        }

        public long Count()
        {
            var sql = Sql.Builder.Select("count(*)");
            sql.From("client");
            return Database.Query<long>(sql).FirstOrDefault();
        }
    }
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re[3]: Entity Framework Core vs Business Logic
От: Sinclair Россия https://github.com/evilguest/
Дата: 07.09.20 04:13
Оценка:
Здравствуйте, 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>?
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[4]: Entity Framework Core vs Business Logic
От: varenikAA  
Дата: 07.09.20 04:49
Оценка:
Здравствуйте, 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# такое не приветствуется. Статика она такая.
☭ ✊ В мире нет ничего, кроме движущейся материи.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.