Entity framework 实体框架6代码优先:特定模型设计实现

Entity framework 实体框架6代码优先:特定模型设计实现,entity-framework,ef-code-first,Entity Framework,Ef Code First,我有一个小模型,但我对如何设计有疑问 我的想法是分为三类:JobReport/Customer/Project。 范围是填充报告,选择客户,然后选择绑定到其客户的项目(加上其他有效负载) 我的设计是: 型号: public class EFDBContext : DbContext { public DbSet<JobReport> JobReport { get; set; } } 公共类EFDBContext:DbContext { 公共数据库集作业报告{get;se

我有一个小模型,但我对如何设计有疑问

我的想法是分为三类:JobReport/Customer/Project。 范围是填充报告,选择客户,然后选择绑定到其客户的项目(加上其他有效负载)

我的设计是:

型号:

public class EFDBContext : DbContext
{
    public DbSet<JobReport> JobReport { get; set; }
}
公共类EFDBContext:DbContext
{
公共数据库集作业报告{get;set;}
}
当我构建JobReport视图并使用其模型时,我发现绑定Customer实体很困难,因为它直接绑定到Project而不是JobReport。 另一个解决方案是将CustomerID和ProjectID都放入JobReport中,但在我看来这是多余的

我认为有两种可能性: 1-保留第一个模型,并分别使用JobReport和Customer创建ViewModel 2-使用第二个模型,以便我拥有所有ID

你觉得怎么样? 您将如何实施此案例

非常感谢


Max

一些观察结果:

  • 设计1似乎是合适的,除非一份工作报告应该能够引用属于不同客户的多个项目
  • ProjectID属性不属于客户类型,对吗?不过,项目集合就在那里
  • 项目类型应该有一个JobReports集合,列出属于特定对象的所有报告
这是一个与关于在领域驱动设计中识别聚合的讨论密切相关的问题。似乎您的客户实体是一个自然的聚合根,这意味着与聚合中的对象的所有交互都必须通过客户进行

这意味着DbContext应该如下所示:

public class EFDBContext : DbContext
{
    public DbSet<Customer> Customers { get; set; }
}
公共类EFDBContext:DbContext
{
公共数据库集客户{get;set;}
}
要获取属于客户的子项,可以使用LINQ遍历关系:

public IEnumerable<JobReport> GetReportsByCustomer(int customerId)
{
    using (var context = new EFDBContext())
    {
        return context.Customers.Where(x => x.CustomerID.Equals(customerId))
            .SelectMany(x => x.Projects)
            .SelectMany(x => x.JobReports)
            .OrderBy(x => x.Timestamp);
    }
}
public IEnumerable GetReportsByCustomer(int-customerId)
{
使用(var context=new EFDBContext())
{
返回context.Customers.Where(x=>x.CustomerID.Equals(CustomerID))
.SelectMany(x=>x.Projects)
.SelectMany(x=>x.JobReports)
.OrderBy(x=>x.Timestamp);
}
}
您还可以选择始终使用客户作为编辑操作的基础,因为它是聚合根。这将涉及将客户从数据库中拉出,并确保包括所有详细数据:

public IEnumerable<Customer> GetCustomer(int customerId)
{
    using (var context = new EFDBContext())
    {
        return context.Customers
            .Include(x => x.Projects.Select(y => y.JobReports))
            .FirstOrDefault(x => x.CustomerID.Equals(customerId));
    }
}
public IEnumerable GetCustomer(int-customerId)
{
使用(var context=new EFDBContext())
{
返回上下文
.Include(x=>x.Projects.Select(y=>y.JobReports))
.FirstOrDefault(x=>x.CustomerID.Equals(CustomerID));
}
}

您需要使用System.Data.Entity手动添加
位于类文件的顶部,以使上述代码正常工作。

您的观察是正确的。我的疑问是决定是否用JobReport欺骗客户。你消除了我的疑虑。谢谢如果我想在Razor之类的东西中验证客户,该怎么办@Html.ValidationMessageFor(model=>model.CustomerID,“,new{@class=“text danger”})那么您似乎是在处理客户实体,而不仅仅是作业报告。请参阅我的更新答案,了解如何访问客户数据及其详细数据。