ahmed_sa Ответов: 1

При вызове get all repository pattern я не нашел ошибку компиляции singleordefaultasync


Проблема

При вызове get all repository pattern я не обнаружил ошибки компиляции singleordefaultasync .

сведения об ошибке

Ienumerable<employee> doesn't contain definition for singleordefaultasync and no accessible extension method singleordefaultasync accepting first argument of type ienumerable<employee> could be found

работа в проекте asp.net ядро 2.1 visual studio 2017

интерфейс репозитория

public interface IrepositoryTab<T> where T : class
        {
            IEnumerable<T> GetAll();
        }


реализация репозитория

public class RepositoryTab<T> : IrepositoryTab<T> where T : class
    {
        protected TabDbContext db { get; set; }
       // private TabDbContext db;
        private DbSet<T> dbSet;

        public RepositoryTab(TabDbContext Tabdb)
        {
            db = Tabdb;
            dbSet = db.Set<T>();
        }
        public IEnumerable<T> GetAll()
        {
            return dbSet.ToList();
        }
        }


Что я уже пробовал:

Ошибка компиляции показать на Создать действие результат функции одно-или умолчанию асинхронный
public class EmployeeController : Controller
    {
        
        private readonly IrepositoryTab<Employee> _repository;
        public EmployeeController(IrepositoryTab<Employee> emp)
        {
            this._repository = emp;
        }
 public async Task<IActionResult> Create(int? nextID)
        {
Employee emp = await _repository.GetAll().SingleOrDefaultAsync(m => m.EmployeeId == NextVal);
        }

Richard MacCutchan

Нет необходимости выделять текст жирным шрифтом. Все здесь вполне способны читать обычный текст.

1 Ответов

Рейтинг:
7

Richard Deeming

Сообщение об ошибке совершенно ясно - нет SingleOrDefaultAsync метод расширения для IEnumerable<T> интерфейс. Данные уже находятся в памяти, поэтому асинхронному методу нечего ждать.

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

public interface IRepositoryTab<T> where T : class
{
    IEnumerable<T> GetAll();
    Task<T> SingleOrDefaultAsync(Expression<Func<T, bool>> predicate);
}

public class RepositoryTab<T> : IRepositoryTab<T> where T : class
{
    ...
    
    public Task<T> SingleOrDefaultAsync(Expression<Func<T, bool>> predicate)
    {
        return dbSet.SingleOrDefaultAsync(predicate);
    }
}

...

public async Task<IActionResult> Create(int? nextID)
{
    Employee emp = await _repository.SingleOrDefaultAsync(m => m.EmployeeId == NextVal);
}

NB: Это все еще непрочная абстракция, так как предикат, который вы передаете, должен быть конвертирован в запрос базы данных. Именно здесь универсальные репозитории падают; конкретный репозиторий будет предоставлять метод для передачи первичного ключа сущности вместо этого. Но с универсальным репозиторием, где вы не знаете, какого типа будет первичный ключ, вы не можете легко сделать это.