2017-06-16 104 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