【发布时间】:2018-10-12 18:03:07
【问题描述】:
以前(使用 .net 4.5.2 和 EF 6 时)。我有一个通用的Get 方法,它接受了如下的一些包含;
public abstract class DataContext : IdentityDbContext<ApplicationUser, ApplicationRole, int>, IDataContext
{
public DataContext(DbContextOptions options)
: base(options)
{
}
// reduced for brevity
public T Get<T>(int id, params Expression<Func<T, object>>[] includes) where T : class, IEntity
{
return this.Set<T>().Include(includes).FirstOrDefault(x => x.Id == id);
}
然后我会打电话给例如;
context.Get<Job>(id,
x => x.Equipment,
x => x.Equipment.Select(y => y.Type));
包括Job.Equipment 和Job.Equipment.Type。
但是,当我将其移植到 asp.net core 2 时。我尝试了相同的通用方法,但如果我尝试包含子实体,则会收到以下错误;
属性表达式“x => {from Equipment y in x.Equipment select [y].Type}”无效。该表达式应表示属性访问:'t => t.MyProperty'。有关包含相关数据的更多信息,请参阅http://go.microsoft.com/fwlink/?LinkID=746393。
谁能建议我如何解决这个问题,以便在我的通用 Get<T> 方法中包含子实体和 Entity Framework Core 2?
更新
通过查看文档,还有一个额外的包含方法
include(string navigationPropertyPath)
我添加了以下方法;
public T Get<T>(int id, string[] includes) where T : class, IEntity
{
var result = this.Set<T>().AsQueryable();
foreach(var include in includes)
{
result = result.Include(include);
}
return result.FirstOrDefault(x => x.Id == id);
}
虽然我不相信这里的效率,但哪个有效?
【问题讨论】:
-
在 Entity Framework Core 中没有接受
Expression<Func<T, object>>[]的Include重载,还是您在 EF6 中使用它的方式? -
.Include工作正常,但似乎选择子实体在核心 2 中发生了变化? (以前运行良好的代码不起作用)。我还找到了链接docs.microsoft.com/en-us/ef/core/querying/related-data,这似乎暗示了.ThenInclude -
是的,您需要使用
ThenInclude,但您的代码甚至无法在 EF Core 2 上为我编译 -
奇怪的是它对我来说编译没问题。我编辑以包含我的
DbContext扩展名。我注意到有一个Include(string navigationPropertyPath)可以完成这项工作。我会对此进行测试并更新我的结果。 -
另一种解决方案是将 lambda 表达式转换为字符串形式的路径:stackoverflow.com/a/47063432/861716