我试图将我的数据库实体从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 select语句而不是构造函数初始化来解决这个问题。
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();
构造函数的想法是这样的,我不需要每次想要上下文时都抛出它。使用此扩展方法也可以实现相同的目的,因为逻辑仍然是封装的。