Eluvium
Eluvium

Reputation: 183

How can I configure many-to-many relationship to my own created entity in entity framework

I have some classes:

public class Values : Entity
    {
        [Key]
        public int Values_ID { get; set; }    
        [Required]
        public string Values_Name { get; set; }    
        [Required]
        public int ValuesNumeric { get; set; }    
        public virtual ICollection<ValuesMetrics> ValuesMetrics { get; set; }
    }

public class GQMetric : Entity
    {
        [Key]
        public int GQMetric_ID { get; set; }

        [Required]
        public string GQMetricName { get; set; }
        [Required]
        public int Importance_ID { get; set; }

        public virtual List<GQMetricsQuestions> GQMetricsQuestions { get; set; }
        public virtual ICollection<ValuesMetrics> ValuesMetrics { get; set; }

        public virtual ImportanceScale ImportanceScale { get; set; }
    }

I need to create many-to-many relationship to my own created class ValuesMetrics, not to automatically generated table by entity framework. I have tried a lot of solutions here, here and here but none of it did not work. Eventually, I did this:

public class ValuesMetrics : Entity
    {
        public int GQMetric_ID { get; set; }
        public int Value_ID { get; set; }

        public virtual GQMetric GQMetric { get; set; }
        public virtual Values Values { get; set; }
    }

FluentAPI:

modelBuilder.Entity<ValuesMetrics>()
               .HasKey(c => new { c.GQMetric_ID, c.Value_ID });

            modelBuilder.Entity<GQMetricsQuestions>()
               .HasKey(c => new { c.GQMetric_ID, c.Question_ID });

but created table (ValuesMetrics) have an excessive relationship (GQMetrics_GQMetric_ID). I need only two primary keys from Values and GQMetrics tables excessive relationship

Can you advice me how to solve this problem? Thanks for any help!

Upvotes: 1

Views: 115

Answers (1)

Botond Botos
Botond Botos

Reputation: 1242

Applied @Esteban 's solution from the link already referenced by you: Create code first, many to many, with additional fields in association table

Basically I did the following three changes:

  1. Used POCO entities instead of inheriting from Entity class
  2. Removed EF attributes, since we'll be using fluent API anyway
  3. Changed fluent API configuration

Resulting code:

public class MyContext : DbContext
{
    public DbSet<Values> Values { get; set; }
    public DbSet<GQMetric> GqMetric { get; set; }
    public DbSet<ValuesMetrics> ValuesMetrics { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Values>().HasKey(values => values.Values_ID);
        modelBuilder.Entity<GQMetric>().HasKey(metric => metric.GQMetric_ID);

        modelBuilder
            .Entity<ValuesMetrics>()
            .HasKey(valuesMetrics => new
            {
                valuesMetrics.Value_ID,
                valuesMetrics.GQMetric_ID
            });

        modelBuilder
            .Entity<ValuesMetrics>()
            .HasRequired(valuesMetrics => valuesMetrics.Values)
            .WithMany(valueMetrics => valueMetrics.ValuesMetrics)
            .HasForeignKey(valueMetrics => valueMetrics.Value_ID);

        modelBuilder
            .Entity<ValuesMetrics>()
            .HasRequired(valuesMetrics => valuesMetrics.GQMetric)
            .WithMany(valueMetrics => valueMetrics.ValuesMetrics)
            .HasForeignKey(valueMetrics => valueMetrics.GQMetric_ID);

        base.OnModelCreating(modelBuilder);
    }
}

public class Values
{
    public int Values_ID { get; set; }
    public string Values_Name { get; set; }
    public int ValuesNumeric { get; set; }
    public virtual ICollection<ValuesMetrics> ValuesMetrics { get; set; }
}

public class GQMetric
{
    public int GQMetric_ID { get; set; }
    public string GQMetricName { get; set; }

    public virtual ICollection<ValuesMetrics> ValuesMetrics { get; set; }
}

public class ValuesMetrics
{
    public int GQMetric_ID { get; set; }
    public int Value_ID { get; set; }

    public virtual GQMetric GQMetric { get; set; }
    public virtual Values Values { get; set; }
}

Upvotes: 1

Related Questions