2017-06-16 25 views
0

以前のバージョンのWebフォームで実現する方法を理解するには、ASP.NETコアを知るには多くの時間がかかると言えますが、ASP.NET Coreはより大きく、より複雑なソリューションを構築することができます。EFコア:円エンティティの参照

私はASP.NET Coreを初めて使い始めました。私はEF Coreと関連するデータを理解しようとしています。私はhttps://docs.microsoft.com/en-us/aspnet/core/data/ef-mvc/introを使用して基礎を学び、最初のASP.NET Coreアプリケーションを作成します。

私は複数のフォーム(フォームエンティティ)を持つことができるエンティティ "標準"を持っています。エンティティは2つの同じプロパティを共有していますので、両方をMasterDocumentというマスタークラスから継承させました。以前はDocumentと呼ばれていました。

標準:

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:私は上のdeletebehaviour.Restrictを挿入ので、これは、円形の要求または円形の削除を引き起こす可能性があることを理解し

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; } 
    } 
} 

標準:

 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); 
     } 
    } 
} 

私は、アプリケーションを実行しようとすると、私はエラーを取得する:

https://docs.microsoft.com/en-us/aspnet/core/data/ef-mvc/introに基づいて

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'.

私が欠けているかを把握することはできませんここに。

あらかじめ、よりクールなWebアプリケーションを作成できるように、ASP.NET Coreについて理解していただきありがとうございます。ありがとう!

ジョンホーコンAriansen

+0

標準とフォームはMasterDocumentから継承しないでください。フィールドを再利用したいのですが、MasterDocument自体はエンティティです。共通フィールドを基本クラスに移動し、すべての基本クラスを使用するだけです。 – jpgrassi

答えて

0

私はあなたが実際にMasterDocumentから継承して多型の実体を持ってしたくないと仮定しています。ですから、私が見るところでは、FormとStandardがMasterDocumentと同じプロパティを共有し、MasterDocument自体がEntityであることを望みます。その場合、それらのプロパティを基本クラスに抽象化するだけです。

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... 
} 

これで解決します。

フォームへのもう1つのアプローチは、フォームと標準でMasterDocument FKを使用することです。そうすれば、テーブルに重複フィールドが表示されなくなります。

さらに改善点:FluentAPIで属性を使用しているすべての設定を達成できることにも注意してください。このように、あなたのクラスはEFのものから切り離しています。それだけでノイズが増え、読みにくくなります。 Fluent API on EF docsの例でなければなりません。

+0

問題を解決した場合は、回答としてマークしてください:) – jpgrassi

+0

返信jpgrassiありがとう!私の最初のコメントは私が終わる前に保存されました。ほんとうにありがとう!さて、クラスMasterDocumentは基本クラスとされていました。 MasterDocumentは別のエンティティではありません。したがって、私はMasterDocumentに 'abstract'を追加し、コンパイルして 'dotnet ef migrationsが継承を追加して実行します。私はまだ移行時に同じエラーが発生します。引数 'clrType'に提供されたエンティティタイプ 'System.Collections.Generic.ICollection'1 [Skjemabasen.Models.Document.Form]は参照型でなければなりません。 –

+0

DBSetからMasterDocumentを削除しましたか? - この行:public DbSet Documents {get;セット; }。 MasterDocumentがエンティティではなく、基本クラスであれば、存在しないはずです。 – jpgrassi

関連する問題