没有 EF Core 的 Linq 异步接口

Ian*_*ick 3 c# linq entity-framework decoupling

假设我在 EF Core 中有一个查询,如下所示:

MethodWithDomainLogic() {
  return this.dbContext.People.Where(...).ToListAsync();
}
Run Code Online (Sandbox Code Playgroud)

现在,为了将我的域层与我的数据访问层分离,我希望这个方法在我的域程序集中,并且该程序集没有对 EFCore 的引用。所以它看起来像:

在领域层:

public interface IEntities {
  IQueryable<Person> People { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

在数据层:

private IEntities entities; // injected with a dbcontext that implements the IEntities interface.

public Task<IEnumerable<Person>> MethodWithDomainLogic() {
  return this.entities.People.Where(...).ToListAsync(); // How to do this without referencing EFCore?
}
Run Code Online (Sandbox Code Playgroud)

根据我的理解,这是不可能的,因为 Linq 本身不支持异步查询。

我已经通过在域层中使用 EFCore 接口设置我自己的接口解决了这个问题(基本上是复制并粘贴了 ToListAsync 和 FirstAsync 等方法......)然后在我的数据层中实现它,只需调用EFCore 版本。然而,这是非常混乱和复杂的。

有更好的解决方案吗?我希望我的域方法在没有 EFCore 的情况下使用异步编程和 Linq,但要在数据层中使用 EFCore 实现 Linq/异步编程。

Dav*_*oft 5

许多您的查询方法需要从您的域层使用的是在EF规定,在框架中没有别处。 ToListAsync()Include(navprop)AsNoTracking(),等。

如果您在域层中编写查询(您绝对应该这样做),并且想要访问所有有用的 EF 功能,则需要对 EF 的引用。

可能没有对 EF 的引用,而只使用IQueryable<T>基础框架中定义的扩展方法的子集,但这会产生成本。并且可以在您的域和 EF 之间放置某种自定义的中间 API,但同样的问题是是否值得付出努力。