我正在尝试将数据库实体从 DbSet 转换为上下文模型。我的数据库当前使用延迟加载来加载导航属性。我能够通过做.Where(d => new ContextClass { Prop1 = d.Prop1, Prop2 = d.Prop2.Prop })
来实现这一点。但是现在假设ContextClass
有一个接受d
的构造函数,并且我在那里初始化属性,我不再能够访问导航属性并遇到延迟加载问题。
我的对象:
public class Entity1
{
public string Prop1 { get; set; }
public virtual Entity2 Prop2 { get; set; }
}
public class Entity2
{
public string Prop { get; set; }
}
public class ContextClass
{
public string Prop1 { get; set; }
public string Prop2 { get; set; }
public ContextClass()
{
}
public ContextClass(Entity1 entity)
{
Prop1 = entity.Prop1;
Prop2 = entity.Prop2.Prop;
}
}
工作查询:
.Select(e => new ContextClass
{
Prop1 = e.Prop1,
Prop2 = e.Prop2.Prop
})
.ToListAsync();
非工作查询:
.Select(e => new ContextClass(e))
.ToListAsync();
这是我得到的错误:
Error generated for warning 'Microsoft.EntityFrameworkCore.Infrastructure.DetachedLazyLoadingWarning: An attempt was made to lazy-load navigation property 'Entity2' on detached entity of type 'Entity1Proxy'. Lazy-loading is not supported for detached entities or entities that are loaded with 'AsNoTracking()'.'. This exception can be suppressed or logged by passing event ID 'CoreEventId.DetachedLazyLoadingWarning' to the 'ConfigureWarnings' method in 'DbContext.OnConfiguring' or 'AddDbContext'.
我能够通过使用扩展方法来执行通常的 LINQ to SQL 选择语句而不是构造函数初始化来解决此问题。
public static IQueryable<ContextClass> SelectAsContext(this IQueryable<Entity1> queryable)
{
return queryable.Select(x => new ContextClass
{
Prop1 = x.Prop1,
Prop2 = x.Prop2.Prop
});
}
所以在调用代码中:
var contexts = await queryable.SelectAsContext().ToListAsync();
构造函数的想法是这样我就不必每次想要上下文时都强制转换它。使用此扩展方法也有相同的目的,因为逻辑仍然是封装的。