Операторы FindAsync и Include LINQ

код, который я получил до сих пор работает нормально

public async Task<ActionResult> Details(Guid? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }

            ItemDetailModel model = new ItemDetailModel();
            model.Item = await db.Items.FindAsync(id);
            if (model.Item == null)
            {
                return HttpNotFound();
            }           
            return View(model);
        }

но я хочу включить 1 таблицу больше и не могу использовать FindAsync

public async Task<ActionResult> Details(Guid? id)
        {
            if (id == null)
            {
                return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
            }

            ItemDetailModel model = new ItemDetailModel();
            model.Item = await db.Items.Include(i=>i.ItemVerifications).FindAsync(id);


            if (model.Item == null)
            {
                return HttpNotFound();
            }           

            return View(model);
        }

поэтому я сталкиваюсь с этой ошибкой

Состояние Подавления Строки Файла Проекта Описания Кода Серьезности Ошибка CS1061 "IQueryable" не содержит определения для "FindAsync" и нет метода расширения "FindAsync", принимающего первый аргумент типа "IQueryable" может быть найден (вам не хватает с помощью директива или ссылка на сборку?)

есть идеи, как это исправить?

2 ответов


самое простое-использовать FirstOrDefaultAsync или SingleOrDefaultAsync вместо:

model.Item = await db.Items.Include(i => i.ItemVerifications)
    .FirstOrDefaultAsync(i => i.Id == id.Value);

причина, по которой вы получаете ошибку, заключается в том, что Find / FindAsync методы определены для DbSet<T>, а Include is IQueryable<T>.

другой способ-объединить FindAsync С явная загрузка:

model.Item = await db.Items.FindAsync(id);
if (model.Item == null)
{
    return HttpNotFound();
}
await db.Entry(model.Item).Collection(i => i.ItemVerifications).LoadAsync();    

Если вы используете общий репозиторий и не знаете PK во время выполнения, этот подход может помочь:

public interface IGenericRepository<TEntity> where TEntity : class
{
    Task<TEntity> Get(int id, string[] paths = null);
}

public class GenericRepository<TEntity> : IGenericRepository<TEntity> where TEntity : class
{
    private readonly ApplicationDbContext _context;
    private readonly DbSet<TEntity> _dbSet;

    public GenericRepository(ApplicationDbContext context)
    {
        _context = context;
        _dbSet = _context.Set<TEntity>();
    }

    public async Task<TEntity> Get(int id, string[] paths = null)
    {
        var model = _dbSet.FindAsync(id);
        foreach (var path in paths)
        {
            _context.Entry(model.Result).Reference(path).Load();
        }
        return await model;
    }
}