#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
Я не думал, что есть лучший ответ, но подумал, что в любом случае стоит спросить 🙂