2017-06-16 62 views
0

我想说,了解ASP.NET Core需要花费大量时间才能理解如何使用webforms实现之前的版本,但我了解ASP.NET Core更大,您可以构建更复杂的解决方案。EF核心:圆形实体参考

我退出了ASP.NET Core,并试图了解EF Core和相关数据。我使用https://docs.microsoft.com/en-us/aspnet/core/data/ef-mvc/intro来学习基础知识并创建我的第一个ASP.NET Core应用程序。

我有一个实体“标准”,可以有多个表单(表单实体)。这些实体共享一些相同的属性,所以我使它们都从一个名为MasterDocument的主类继承而来。以前称为文档。

标准:

namespace Skjemabasen.Models.Document 
{ 
    public class Standard : MasterDocument 
    { 
     [Display(Name = "Kategori")] 
     public virtual Category Category { get; set; } 
     [Display(Name = "Dokumenter")] 
     public ICollection<Form> Forms { get; set; } 
    } 
} 

形式:

public class Form : MasterDocument 
{ 
    public Format Format { get; set; } 
    public virtual Member Assignee { get; set; } 
    public String Status { get; set; } 
    [ForeignKey("Standard")] 
    public int StandardId { get; set; } 
    public Standard Standard { get; set; } 
    public ICollection<Customer.Subscription> Subscribers { get; set; } 
} 

MasterDocument:

namespace Skjemabasen.Models.Document 
{ 
    public class MasterDocument : IDocument 
    {  
     public int ID { get; set; } 
     [Required] 
     [Display(Name = "EStandard")] 
     [StringLength(50)] 
     public string EStandard { get; set; } 
     [Required] 
     [Column("Betegnelse")] 
     [Display(Name = "Betegnelse")] 
     [StringLength(60)] 
     public string Betegnelse { get; set; } 
     [Display(Name = "Kommentar")] 
     public string Comment { get; set; } 
    } 
} 

据我所知,这可能会导致圆形请求或圆形缺失,所以我上插入一个deletebehaviour.Restrict标准:

 modelBuilder.Entity<Standard>() 
      .HasOne(d => d.Forms) 
      .WithMany() 
      .OnDelete(DeleteBehavior.Restrict); 

我的完整的上下文类:

namespace Skjemabasen.Data 
{ 
    public class SkjemabasenContext : DbContext 
    { 
     public SkjemabasenContext(DbContextOptions<SkjemabasenContext> options) :base(options) 
     { 

     } 

     public DbSet<Member> Members { get; set; } 
     public DbSet<Category> Categories { get; set; } 
     public DbSet<Standard> Standards { get; set; } 
     public DbSet<Form> Forms { get; set; } 
     public DbSet<Customer> Customers { get; set; } 
     public DbSet<Revision> Revisions { get; set; } 
     public DbSet<Subscription> Subscriptions { get; set; } 
     public DbSet<MasterDocument> Documents { get; set; } 

     public IQueryable<Customer> CurrentCustomers 
     { 
      get { return Customers.Where(c => c.Inactive == false); } 
     } 

     public IQueryable<Customer> InActiveCustomers 
     { 
      get { return Customers.Where(c => c.Inactive == true); } 
     } 

     protected override void OnModelCreating(ModelBuilder modelBuilder) 
     { 

      modelBuilder.Entity<Member>().ToTable("Member"); 
      modelBuilder.Entity<Category>().ToTable("Category"); 
      modelBuilder.Entity<Standard>().ToTable("Standard"); 
      modelBuilder.Entity<Form>().ToTable("Form"); 
      modelBuilder.Entity<Customer>().ToTable("Customer"); 
      modelBuilder.Entity<Revision>().ToTable("Revision"); 
      modelBuilder.Entity<Subscription>().ToTable("Subscription"); 
      modelBuilder.Entity<MasterDocument>().ToTable("Document"); 


      modelBuilder.Entity<Standard>() 
       .HasOne(d => d.Forms) 
       .WithMany() 
       .OnDelete(DeleteBehavior.Restrict); 
     } 
    } 
} 

当我尝试运行应用程序,我得到的错误:

System.ArgumentException: 'The entity type 'System.Collections.Generic.ICollection`1[Skjemabasen.Models.Document.Form]' provided for the argument 'clrType' must be a reference type.' Because all Forms must have a parent Standard and both 'Standard' and 'Form' inherits from MasterDocument, I understand that ASP.NET Core warns about circular deletion, but I'm not sure how to achieve this. The error says something about ICollection of 'Forms' not being a reference type. Is something missing in 'Standard' related to the relation between and 'Form'.

基于https://docs.microsoft.com/en-us/aspnet/core/data/ef-mvc/intro我想不出什么我失踪这里。

提前非常感谢您帮助我理解ASP.NET Core,以便创建更多酷的Web应用程序。谢谢!

乔恩·哈康Ariansen

+0

标准和表格不应从MasterDocument继承。我知道你想重用字段..但MasterDocument本身就是一个实体。只需将公共字段移动到基类并在所有基类上使用基类即可。 – jpgrassi

回答

0

我假设你实际上并不想从MasterDocument继承有多态性实体。所以,从我所看到的,你希望Form和Standard共享MasterDocument的相同属性,而MasterDocument本身就是一个实体。如果是这样的话,只需将这些属性抽象到基类:

public abstract class MasterBaseDocument 
{  
    public int ID { get; set; } 
    [Required] 
    [Display(Name = "EStandard")] 
    [StringLength(50)] 
    public string EStandard { get; set; } 
    [Required] 
    [Column("Betegnelse")] 
    [Display(Name = "Betegnelse")] 
    [StringLength(60)] 
    public string Betegnelse { get; set; } 
    [Display(Name = "Kommentar")] 
    public string Comment { get; set; } 
} 

public class Form : MasterBaseDocument 
{ 
    ... 
} 
public class Standard : MasterBaseDocument 
{ 
    ... 
} 

public class MasterDocument : MasterBaseDocument 
{ 
    // right now, empty here... 
} 

这应该解决它。

您的模型的另一种方法是在Form和Standard上具有MasterDocument FK。这样你就不会在表格上得到重复的字段。

进一步改进:另外,请记住,您可以实现所有使用FluentAPI属性的配置。这样你的类就可以保持并与EF的东西分离。这只是增加了噪音,使其很难阅读。在EF文档上也应该是流利API的例子。

+0

如果解决了这个问题,请确保您标记为答案:) – jpgrassi

+0

非常感谢您的回复jpgrassi!我的第一条评论是在我完成之前保存的。对此,我真的非常感激!那么,MasterDocument类应该是基类。 MasterDocument不是另一个实体。因此,我在MasterDocument中添加了'abstract',编译并运行'dotnet ef migrations add Inheritance'。我仍然在迁移过程中遇到同样的错误。为参数'clrType'提供的实体类型'System.Collections.Generic.ICollection'1 [Skjemabasen.Models.Document.Form]'必须是引用类型。 –

+0

您是否从DBSet中删除了MasterDocument? - 这一行:public DbSet Documents {get;组; }。如果MasterDocument不是一个实体,只是一个基类,不应该在那里。 – jpgrassi