Уровень доступа к данным C # для обоих существующих ADO.NET код и EF

#c# #entity-framework #ado.net

#c# #entity-framework #ado.net

Вопрос:

У меня есть приложение на c #, в котором есть уровень репозитория, который обращается к базе данных. Я также хотел бы поддерживать SQL Server, что можно было бы сделать, написав набор классов, которые используют System.Data.SqlClient (приложение уже использует интерфейсы, поэтому это должно быть достаточно просто).

Однако я рассматриваю возможность использования EF в моем новом уровне данных.

Мой вопрос в том, что в моем шаблоне репозитория для EF есть Get, который выглядит следующим образом:

    public IQueryable<TEntity> Get(Expression<Func<TEntity, bool>> filter = null, 
        Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null, 
        string includeProperties = "")
    {
        IQueryable<TEntity> query = DbSet;

        if (filter != null)
            query = query.Where(filter);

        foreach (var includeProperty in includeProperties.Split
            (new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
        {
            query = query.Include(includeProperty);
        }

        if (orderBy != null)
            return orderBy(query);

        return query;
    }
 

Очень полезно для выполнения таких действий, как

 repo.Get(x => x.MyColumn == "Value").ToList(); 
 

например.

Существующий уровень данных приложений делает что-то другое, что не так хорошо, но обеспечивает аналогичную вещь:

 public virtual IEnumerable<T> GetAll(string whereSql = "", params IDbDataParameter[] parameters)
 

Я не вижу никакой альтернативы, кроме как заменить эти вызовы конкретными методами репозитория, например GetAllOrdersForCustomer(Guid customerId) . таким образом, оба уровня данных достижимы.

Похоже, это мой выбор — написать слой данных SQL для SQL Server или изменить приложение, чтобы иметь определенные шаблоны репозитория, чтобы я мог поддерживать EF.

Есть ли у кого-нибудь идеи о том, как я мог бы использовать первый метод для генерации WHERE предложений? В любом случае это лучший способ, потому что он вводится, а не содержит строку с a WHERE , которая может содержать что угодно.

Комментарии:

1. Вам не нужен уровень «репозитория», для этого и существует EF. EF сам генерирует инструкции SQL и выполняет их с помощью ADO.NET . Использование низкоуровневого «универсального» репозитория поверх высокоуровневого ORM, такого как EF, является уродливым антишаблоном . Фактически, DbSet — это реализация репозитория, DbContext — это многоцелевая единица работы

2. Ваша проблема показывает, почему «универсальный» репозиторий является таким уродливым антипаттером. С помощью LINQ вы можете просто указать нужные условия и даже объединить несколько из них, связав Where() предложения. Теперь вы даже не можете написать простой Where

3. Реальный выбор — удалить весь этот код и просто использовать EF. Используйте специализированный репозиторий для абстрагирования конкретных операций и проверок. Прочитайте книгу Гуннара Пейпмана » Нет необходимости в репозиториях и единице работы с Entity Framework Core «. В этом нет ничего нового, репозиторий — это новый синглтон с 2009 года.

4. может быть, и это будет интересно почитать

5. Почему вы вообще использовали «репозиторий»? Шаблоны предназначены для решения конкретных проблем в конкретных ситуациях. Молоток — это хорошие гвозди, плохие для шурупов. Существует много copypasta (не опечатка) о «лучших практиках» и даже о некоторых «фреймворках», которые добавляют все причудливые функции на веб-сайт, независимо от того, имеют они смысл или нет

Ответ №1:

Жаль, что мой комментарий находится внизу и не отображается, если вы не попросите просмотреть больше комментариев, потому что мой вопрос был кем-то отредактирован, и все, кроме vasily.sib, неправильно поняли вопрос. Если бы ответом было просто использовать EF, я бы не задал вопрос, не так ли?

Это существующий уровень хранилища, который поддерживает базу данных, которую EF не поддерживает.

Единственный вариант, который, я думаю, у меня есть, — это удалить несколько нечетных мест, где я использую методы fancy WHERE, и заменить их точным запрашиваемым путем доступа, например

репо.GetById или customerrepo.GetOrders

Я не думал, что есть лучший ответ, но подумал, что в любом случае стоит спросить 🙂