#c# #entity-framework-core #repository-pattern
#c# #entity-framework-core #репозиторий-шаблон
Вопрос:
Я создал a Generic Repository
, который может помочь мне в моих проектах.
Проблема:
В эти дни я работаю над проектом и хочу получить данные из некоторых связанных таблиц (все данные из одной таблицы, а также загрузить все связанные данные из других таблиц, которые я выбираю), созданный мной репозиторий не может справиться с этим, и я не хочу работать напрямую с Entity Framework Core.
Мой репозиторий:
Мой репозиторий — это проект с открытым исходным кодом, вы можете посмотреть исходный код здесь.
Чего я хочу именно:
Моя идея состоит в том, чтобы создать метод в my generic repository
, этот метод получит объект, из которого я хочу выбрать данные, и получит выражение, которое сообщает ему загружать данные из объекта scent и некоторых связанных таблиц (не все связанные таблицы, а некоторые связанные таблицы, которые я отправлю в выражении).
Как я могу это решить?
Комментарии:
1. Если шаблон репозитория мешает, не используйте его….
Ответ №1:
Это сильно зависит от вашей конкретной реализации общего репозитория, но следующий код может помочь вам понять идею —
public async Task<TEntity> LoadSingleWithRelatedAsync<TEntity>(TEntity entity, params Expression<Func<TEntity, object>>[] expressionList) where TEntity : EntityBase
{
if (entity == null)
return null;
var query = _DbCtx.Set<TEntity>().AsQueryable();
foreach (var expression in expressionList)
{
query = query.Include(expression);
}
return await query.FirstOrDefaultAsync(p => p.Id == entity.Id);
}
где EntityBase
—
public class EntityBase
{
public int Id { get; set; }
}
Ниже приведен пример того, как вы могли бы его использовать —
// Order has a Customer parent and a list of OrderLine children
var loadedOrder = await _Repo.LoadSingleWithRelatedAsync(order, p => p.Customer, p => OrderLines);
Order
должен быть класс, производный отEntityBase
order
может бытьDetached
объектом (например, полученным через параметр метода со стороны клиента) или уже существующим объектом, извлеченным из базы данных
РЕДАКТИРОВАТЬ: 2021.04.01
Если вам нужна коллекция вместо одного объекта, метод может выглядеть следующим образом —
public async Task<IEnumerable<TEntity>> LoadAllWithRelatedAsync<TEntity>(params Expression<Func<TEntity, object>>[] expressionList) where TEntity : class
{
var query = _DbCtx.Set<TEntity>().AsQueryable();
foreach (var expression in expressionList)
{
query = query.Include(expression);
}
return await query.ToListAsync();
}
Здесь —
TEntity
не требуется иметь ограничениеEntityBase
типа, поскольку мы не используем этоId
свойство- Параметр
entity
не нужен, поскольку мы не ищем конкретную сущность - Чтобы идентифицировать тип в вызывающем коде, параметр type должен использоваться при вызове метода —
// Order has a Customer parent and a list of OrderLine children
var orderList = await _Repo.LoadAllWithRelatedAsync<Order>(p => p.Customer, p => OrderLines);
Комментарии:
1. Во-первых, огромное спасибо за ваше время и усилия, но я в замешательстве, как я могу отправить order в последнем примере использования, который вы предоставили, я не знаю, должен ли я отправлять
Order
параметр как объект типа илиOrder
класса или что? И еще раз огромное спасибо, брат, я действительно ценю это для тебя2. @DEV Пожалуйста, проверьте
EDIT
.3. Действительно, я ценю это для вашего брата, огромное спасибо за ваше время и усилия, у меня есть еще один вопрос ответ, который я предоставил ниже вашего ответа, что вы думаете об этом, другими словами, решение, которое я предоставил ниже вашего ответа , имеет проблемы с производительностью или другие проблемы?? И еще раз огромное спасибо, брат
4. @DEV Я обновил сообщение и код, пожалуйста, проверьте. В коде вашего ответа есть проблема —
ToList()
возвращает новый список при каждом вызове, поэтомуresult
вы получите только последний включенный связанный объект. Вы тестировали код?5.Пожалуйста, не могли бы вы обновить свой ответ, чтобы вернуть список записей из отправленных
entity
, а также загрузить все связанные объекты, потому что мнеlist
вообще нужны записи, а также еще один вопрос, если я не буду использоватьbaseEntity
Id
то, что я могу сделать? и действительно огромное спасибо