The navigation on entity type has not been added to the model, or ignored, or entityType ignored

asp.net-core c# dnx entity-framework entity-framework-core

Question

The navigation 'Tags' on entity type 'Notepad.Models.Note' has not been added to the model, or ignored, or entityType ignored.

public class Note
    {
        public Note()
        {
            CreationDate = DateTime.Now;
            Tags = new HashSet<Tag>();
            Parts = new HashSet<Part>();
        }

        public int ID { get; set; }
        public virtual ICollection<Tag> Tags { get; set; }
        public virtual ICollection<Part> Parts { get; set; }
        public DateTime? CreationDate { get; set; }
    }


public class Tag
    {
        public Tag()
        {
            Notes = new HashSet<Note>();
        }

        public int ID { get; set; }
        public string Name { get; set; }

        public virtual ICollection<Note> Notes { get; set; }
    }

It happens while adding a migration:

dnx ef migrations add DbData -c DataDbContext

Why do you think it happens?

EDIT: DataDbContext:

public class DataDbContext : DbContext
    {
        public DbSet<Note> Notes { get; set; }
        public DbSet<Tag> Tags { get; set; }
        public DbSet<Part> Parts { get; set; }
    }

Accepted Answer

You have Many-to-many relationship there. As the documentation says: http://docs.efproject.net/en/latest/modeling/relationships.html#id21

Many-to-many relationships without an entity class to represent the join table are not yet supported. However, you can represent a many-to-many relationship by including an entity class for the join table and mapping two separate one-to-many relationships.

So you must create additional "join" class like this:

public class NoteTag
    {
        public int NoteId { get; set; }
        public Note Note { get; set; }

        public int TagId { get; set; }
        public Tag Tag { get; set; }
    }

then, replace

 ICollection<Tag> Tags {set;get}

in your Note class to

 ICollection<NoteTag> NoteTags {set;get}

and also in Tag class:

ICollection<Note> Notes {set;get;}

to

ICollection<NoteTags> NoteTags {set;get}

and then override OnModelCreating method in DbContext:

protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            modelBuilder.Entity<NoteTag>()
                .HasKey(t => new { t.NoteId, t.TagId });

            modelBuilder.Entity<NoteTag>()
                .HasOne(pt => pt.Note)
                .WithMany(p => p.NoteTags)
                .HasForeignKey(pt => pt.NoteId);

            modelBuilder.Entity<NoteTag>()
                .HasOne(pt => pt.Tag)
                .WithMany(t => t.NoteTags)
                .HasForeignKey(pt => pt.TagId);
        }

Popular Answer

I am using EF 7, this problem took around 2 hours of my week end. :) So, here is the simple solution - I am having a profile class like this -

[Table("Profile")]
public class Profile
{
    public Profile()
    {

    }

    [Column(Order = 1)]
    [Key]        
    public Guid ProfileID { get; set; }
    [JsonIgnore]
    public virtual ICollection<StudentLivingWith> StudentProfileMap { get; set; }

    [JsonIgnore]
    public virtual ICollection<StudentLivingWith> ParentProfileMap { get; set; }
}

I am using the ProfileID as a F-Key reference in my another table named "StudentLivingWith". (ya, I know the name is bit strange. :)) As you can see in below class, both the columns "StudentProfileID" and "ParentProfileID" refering to the same column "profileID" of my "Profile" table.

[Table("StudentLivingWith")]
public class StudentLivingWith
{
    public StudentLivingWith()
    {

    }

    [Column(Order = 1)]
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int StudentLivingWithID { get; set; }

    [Column(Order = 2)]
    [ForeignKey("StudentProfileID")]
    public Guid StudentProfileID { get; set; }

    [Column(Order = 3)]
    [ForeignKey("ParentProfileID")]
    public Guid ParentProfileID { get; set; }

    [JsonIgnore]
    [InverseProperty("StudentProfileMap")]
    public virtual ICollection<Profile> StudentProfile { get; set; }

    [JsonIgnore]
    [InverseProperty("ParentProfileMap")]
    public virtual ICollection<Profile> ParentProfile { get; set; }
}    

So the conclusion is - you just need to add [InverseProperty] tag on the reference, and this simple solution did the trick for me.

I hope this will help. Thanks.



Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why