2017-06-16 3 views
0

Je dirais qu'il faut beaucoup de temps pour apprendre à connaître ASP.NET Core pour comprendre comment réaliser des choses que les versions précédentes avec des formulaires Web, mais je comprends que ASP.NET Core est plus grand et vous êtes capable de construire des solutions plus complexes.EF Core: référence d'entité circulaire

Je suis nouveau à ASP.NET Core et j'essaie de comprendre les données EF Core et les données connexes. J'utilise https://docs.microsoft.com/en-us/aspnet/core/data/ef-mvc/intro pour apprendre les bases et créer ma première application ASP.NET Core.

J'ai une entité "Standard" qui peut avoir plusieurs formulaires (Entité de formulaire). Les enitités partagent deux propriétés similaires, ce qui fait que j'ai hérité d'une classe de maître appelée MasterDocument. Auparavant appelé Document.

Standard:

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

Forme:

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

Je comprends que cela peut causer la demande circulaire ou la suppression circulaire donc j'inséré un deletebehaviour.Restrict sur Standard:

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

Ma classe complète de contexte:

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

Lorsque je tente de lancer l'application, je reçois l'erreur:

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

Basé sur https://docs.microsoft.com/en-us/aspnet/core/data/ef-mvc/intro Je ne peux pas comprendre ce que je suis absent ici. En avance, merci beaucoup de m'avoir aidé à comprendre ASP.NET Core afin de pouvoir créer des applications web plus sympas. Merci!

Jon Haakon Ariansen

+0

Standard et Form ne doivent pas hériter de MasterDocument. Je comprends que vous voulez réutiliser des champs .. mais MasterDocument lui-même est une entité.Déplacez simplement les champs communs dans une classe de base et utilisez la classe de base sur chacun d'entre eux. – jpgrassi

Répondre

0

Je suppose que vous ne voulez pas vraiment avoir des entités polymorphes en héritant de MasterDocument. Donc, d'après ce que je vois, vous voulez que Form et Standard partagent les mêmes propriétés de MasterDocument alors que MasterDocument est lui-même une Entité. Si c'est le cas, écrivez simplement ces propriétés à une classe de base:

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

Cela devrait résoudre le problème.

Une autre approche de votre modèle serait d'avoir un FK MasterDocument sur les formulaires et les standards. De cette façon, vous n'obtenez pas les champs de doublons sur les tables.

Amélioration supplémentaire: Gardez également à l'esprit que vous pouvez réaliser toutes ces configurations avec FluentAPI. De cette façon, vos cours sont conservés et découplés des contenus EF. Cela ajoute juste du bruit et rend très difficile à lire. Il devrait aussi s'agir d'exemples sur l'API Fluent sur les documents EF.

+0

Si résolu le problème, assurez-vous de marquer comme une réponse :) – jpgrassi

+0

Merci beaucoup pour votre réponse jpgrassi! Mon premier commentaire a été enregistré avant que j'aie fini. J'apprécie vraiment cela! Eh bien, la classe MasterDocument était supposée être la classe de base. MasterDocument n'est pas une autre entité. J'ai donc ajouté 'abstract' à MasterDocument, compilé et lancé 'dotnet ef migrations add Inheritance. Je reçois toujours la même erreur sur la migration. Le type d'entité 'System.Collections.Generic.ICollection'1 [Skjemabasen.Models.Document.Form]' fourni pour l'argument 'clrType' doit être un type de référence. –

+0

Avez-vous retiré le MasterDocument du DBSet? - Cette ligne: public DbSet Documents {get; ensemble; } Si MasterDocument n'est pas une entité et seulement une classe de base, il ne devrait pas être là. – jpgrassi