Search code examples
c#entity-framework-coremany-to-many

EF Core doesn't recognize many-to-many relationship


I have a many-to-many relationship, but EF Core does not seem to recognize it.

The relationship exists between JobOffer and JobOfferTag. JobOffer inherits from BaseJobOffer:

public class BaseJobOffer
{
    [Required]
    [TrimmedStringLength(50, 20)]
    public required string Title { get; set; }

    [Required]
    [TrimmedStringLength(500, 100)]
    public required string Description { get; set; }

    [Required]
    [Range(5, int.MaxValue)]
    public required int PaymentInDollars { get; set; }

    [Required]
    public required PaymentMethod PaymentMethod { get; set; }
    
    public BaseJobOffer()
    {
    }

    [SetsRequiredMembers]
    public BaseJobOffer(BaseJobOffer offer)
    {
        Title = offer.Title;
        Description = offer.Description;
        PaymentInDollars = offer.PaymentInDollars;
        PaymentMethod = offer.PaymentMethod;
    }
}

JobOffer.cs

public class JobOffer : BaseJobOffer
{
    public int Id { get; set; }
    public DateTimeOffset Created { get; private set; } = DateTimeOffset.UtcNow;
    public ICollection<JobOfferTag> Tags = []; // Reference navigation for many to many relationship

    public long UserId { get; set; }
    public ApplicationUser User { get; set; } = null!;

    public JobOffer() : base()
    {
    }

    [SetsRequiredMembers]
    public JobOffer(BaseJobOffer offer) : base(offer)
    {
    }
}

JobOfferTag.cs

public class JobOfferTag
{
    public int Id { get; set; }
    public required string Value { get; set; }

     // Reference navigation for many to many relationship
    public ICollection<JobOffer> JobOffers { get; set; } = []; 
}

EF Core only creates joboffers and joboffertag tables with joboffers having a JobOfferTagId column which should not be the case at all. I expect EF Core to create a join table instead.


Solution

  • I think for the automatic discovery of the many-many-relationship you need to do this:

    public class JobOffer : BaseJobOffer
    {
        public int Id { get; set; }
        public DateTimeOffset Created { get; private set; } = DateTimeOffset.UtcNow;
        public ICollection<JobOfferTag> JobOfferTags { get; set; }
    
        public long UserId { get; set; }
        public ApplicationUser User { get; set; } = null!;
    }
    

    And:

    public class JobOfferTag
    {
        public int Id { get; set; }
        public required string Value { get; set; }
        public ICollection<JobOffer> JobOffers { get; set; } 
    }
    

    Here you can find the Collection Conventions of EF-Core.

    See also all EF-Core-Conventions