【发布时间】:2020-06-06 08:14:03
【问题描述】:
我的目标是使用 DBContext 异步加载相关实体。
让我们想象两个项目。第一个名为MyApp.Domain 并包含域实体。
namespace MyApp.Domain
{
public class PlanPage
{
public Guid Id { get; set; }
}
}
namespace MyApp.Domain
{
public class PlanPageDay
{
public Guid Id { get; set; }
public Guid PlanPageId { get; set; }
}
}
第二个项目名为MyApp.Infrastructure.EntityFramework,包含投影实体到数据库的配置。它还包含扩展领域实体并实现实体框架特定逻辑的类。
namespace MyApp.Infrastructure.EntityFramework.Models
{
public class PlanPageEntity : PlanPage
{
private readonly ApplicationDbContext _applicationDbContext;
protected PlanPageEntity(ApplicationDbContext applicationDbContext)
{
_applicationDbContext = applicationDbContext;
}
public ICollection<PlanPageDay>? Days { get; set; }
public async Task<ICollection<PlanPageDay>> GetDays()
{
return Days ??= await _applicationDbContext.PlanPageDays
.Where(pd => pd.PlanPageId == Id)
.ToListAsync();
}
}
}
这个例子的目的很简单。我们将基础设施代码与域代码分开。看看我们打算如何使用这个概念:
// Entity initializing code. Placing somewhere in domain logic.
var plan = new PlanPage(/*some constructor arguments*/);
// Entity loading code. Placing somewhere in infrastructure implementation.
public async Task<PlanPage> GetPlanPage(Guid id)
{
return await _applicationDbContext.Set<PlanPageEntity>().FindAsync(id);
}
请注意,我们告诉实体框架使用子类 (PlanPageEntity),以便它可以处理所有可以处理的特定事情。
问题是:是否可以配置 EF 以便我们使用这个概念?
【问题讨论】:
-
您应该定义独立于域实体的 ef 实体。使用映射器在它们之间进行映射,但没有继承。
-
这破坏了主题概念。目标是在域内提供加载器。 Mapper 需要与原始对象分开构造新对象。
-
我完全同意 Rufo 爵士的观点:将域逻辑中的模型与数据访问模型混合是一个坏主意。你的头疼只会越来越严重,这听起来像是一场维护噩梦。
-
感谢您的意见。然而,对我来说,这是可悲的。这个概念看起来是一个很好的解决方案。在这种情况下,我不得不寻找另一种实现方式。
-
@Xerillio,你能发表一个合理的反驳作为答案吗?我不是这个想法的唯一支持者,我想为其他寻求解决方案的人解决这个问题。
标签: c# entity-framework design-patterns orm