Click here to Skip to main content
15,892,161 members
Please Sign up or sign in to vote.
1.00/5 (1 vote)
See more: , +
Problem

When Call get all repository pattern i dont found singleordefaultasync compile error .

error details

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

work in project asp.net core 2.1 visual studio 2017

repository interface

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


repository implementaion

C#
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();
        }
        }


What I have tried:

Error compile show on create action result function singleor default async
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);
        }
Posted
Updated 25-Jan-19 5:24am
v2
Comments
Richard MacCutchan 25-Jan-19 11:07am    
It is not necessary to put text in bold. Everyone here is quite capable of reading normal text.

1 solution

The error message is perfectly clear - there is no SingleOrDefaultAsync extension method for the IEnumerable<T> interface. The data is already in memory, so there's nothing for an async method to wait for.

Your repository is badly designed. Rather than loading the entire database into memory just to find a single record, you should add a method to your repository to load just the record you're looking for:
C#
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: This is still a leaky abstraction, since the predicate you pass in must be convertible to a database query. This is where generic repositories fall down; a concrete repository would provide a method to pass in the entity's primary key instead. But with a generic repository, where you don't know what type the primary key will be, you can't easily do that.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900