Mapping for a self-referencing object in EF Code First

My database has a Category table, with columns Id, CategoryName, ParentCategoryId, where ParentCategoryId has a restriction on Category.Id.

I first use the entity code of the entity where the object looks like this:

public class Category { public long Id { get; private set; } public string CategoryName { get; private set; } public long? ParentCategoryId { get; private set; } public Category ParentCategory { get; private set; } public virtual ICollection<Category> SubCategories { get; private set; } } 

If I try to run a query against this, I get an exception:

  The relationship 'ComplaintModel.FK_Complaint_Category' was not loaded because the type 'ComplaintModel.Category' is not available.\r\nThe following information may be useful in resolving the previous error:\r\nThe required property 'Category1' does not exist on the type 'EC.Complaint.Services.Command.Domain.Entities.Category'.\r\n\r\n"} System.Exception {System.Data.MetadataException} 

So it seems like navigation properties are needed for this if I add the following:

  public ICollection<Category> Category1 { get; private set; } public long? Category2Id { get; private set; } public Category Category2 { get; private set; } 

the request is executed.

But, of course, I do not need the properties Category1 and Category2, I want to use the properties ParentCategory and SubCategories.

How can I first specify the code to use the correct navigation properties?

+4
source share
3 answers

your POCO class should look like this:

 public class Category { public long Id { get; private set; } public string CategoryName { get; private set; } public long? ParentCategoryId { get; private set; } public virtual Category ParentCategory { get; private set; } public virtual ICollection<Category> SubCategories { get; private set; } } public class CategoryConfiguration : EntityTypeConfiguration<Category> { public CategoryConfiguration() { this.HasKey(x => x.Id); this.HasMany(category => category.SubCategories) .WithOptional(category => category.ParentCategoryId) .HasForeignKey(course => course.UserId) .WillCascadeOnDelete(false); } } 
+6
source

Entity Framework 6 handles this. You just need to make sure that the Key annotation is used to identify the primary key. Not sure if it works with the virtual keyword or not.

  public class Category { [Key] public long Id { get; private set; } public string CategoryName { get; private set; } public long? ParentCategoryId { get; private set; } public Category ParentCategory { get; private set; } public ICollection<Category> SubCategories { get; private set; } } 
+4
source

I think I found it, I added the following in the OnModelCreating operation:

  modelBuilder.Entity<Domain.Entities.Category>().HasOptional<Category>(c => c.ParentCategory).WithMany().Map(m => m.MapKey(new string[] { "Id", "ParentCategoryId" })); 

and now the ParentCategory and SubCategories properties work (and I can remove categories 1 and category 2). I don't know exactly why SubCategories works, though ...

0
source

Source: https://habr.com/ru/post/928184/


All Articles