FindAsync和Include LINQ语句

时间:2016-11-01 12:57:02

标签: c# linq entity-framework-6

到目前为止,我所获得的代码工作正常

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&#39; IQueryable&#39;不包含的定义   &#39; FindAsync&#39;没有扩展方法&#39; FindAsync&#39;接受第一个   类型的论证&#39; IQueryable&#39;可以找到(你错过了吗?   使用指令或程序集引用?)

有任何线索如何解决?

3 个答案:

答案 0 :(得分:36)

最简单的方法是使用FirstOrDefaultAsyncSingleOrDefaultAsync代替:

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

您收到错误的原因是因为为Find定义了FindAsync / DbSet<T>方法,但Include的结果为IQueryable<T>。< / p>

另一种方法是将FindAsyncexplicit loading结合使用:

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

答案 1 :(得分:4)

如果您使用的是通用存储库,并且在运行时不了解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 = await _dbSet.FindAsync(id);
        foreach (var path in paths)
        {
            _context.Entry(model).Reference(path).Load();
        }
        return model;
    }
}

答案 2 :(得分:2)

使用可靠的原则和领域设计进行编程时,请使用泛型。存储库模式使用泛型类。我将lambda表达传递给GetObjectsQueryable函数。我使用代码优先处理栏来设置延迟加载。但是,我正在远离延迟加载并实现微服务架构。 include表是一个字符串,您可以使用nameof(xxclass)函数来确保名称正确。该函数返回IQueryable结果。可以通过其派生类使用存储库类方法,以增强该方法的保护。这是一个dotnet.core演示。

`

公共类存储库,其中T:类{

public IQueryable<T> GetObjectsQueryable(Expression<Func<T, bool>> predicate,string includeTable="")
    {
        IQueryable<T> result = _dbContext.Set<T>().Where(predicate);
        if (includeTable != "")
        {
            result=result.Include(includeTable);
        }


            return result;
    }

}`