Cristian Diaconescu
Cristian Diaconescu

Reputation: 35641

Can't define two relationships between the same two entities

I can't get EF 6 Code First to map the following two relationships the way I want them.

There are two entities: Template and TemplateVersion.

Every TemplateVersion has exactly one ParentTemplate.

A Template has a collection of TemplateVersions.

This was the first, simple, 1:many relationship, with navigation properties on both sides.

Now for the second:

From all TemplateVersions associated to a Template, only one (e.g. the "newest") is the CurrentTemplateVersion for that Template.

So: Template has a navigation property CurrentVersion, and an associated property CurrentVersionId. There is no corresponding navigation property on the TemplateVersion side.

So, I would say, this second Template : TemplateVersion relation is 0..1 : 1.

Here are the models:

public class Template
{
    public int Id { get; set; }
    [...]
    public virtual int CurrentVersionId { get; set; }
    public virtual TemplateVersion CurrentVersion { get; set; }

    public virtual ICollection<TemplateVersion> Versions { get; set; }
}

public class TemplateVersion
{
    public int Id { get; set; }
    [...]
    public virtual int ParentTemplateId { get; set; }
    public virtual Template ParentTemplate { get; set; }
}

I like to keep my model classes free from DB specifics, so I defined the relationships in the context:

   protected override void OnModelCreating(DbModelBuilder modelBuilder)
   {
        modelBuilder.Entity<Template>()
            .HasMany(template => template.Versions)
            .WithRequired(version => version.ParentTemplate)
            ;

        modelBuilder.Entity<Template>()
            .HasRequired(template => template.CurrentVersion)
            .WithOptional()
            ;
   }

The problem is, the 2nd relation doesn't work as expected.

Using EF Power Tools plugin, I reverse-engineer the model diagram. Here's what I get:

1st relation, 1:many (ok)

enter image description here

2nd relation, 0..1:1

Notice that CurrentVersionId property is not part of the relation, and Template.Id is !

enter image description here

The generated DB tables mirror exactly this: CurrentVersionId is not part of any foreign key, and Id on the Template table incorrectly is defined as a foreign key to Id on the TemplateVersion table.

What am I missing ?

PS. Even if I remove the 1st relationship completely, the 2nd one is the same.

Upvotes: 1

Views: 95

Answers (1)

ocuenca
ocuenca

Reputation: 39326

In a one-to-one relationship, EF requires the PK of the dependent end also has to be the FK of the relationship:

public class Foo
{
   public int Id{get;set;}
   //...
}
public class Boo
{
   [Key,ForeignKey("Foo")]
   public int FooId{get;set;}
   public virtual Foo Foo{get;set;}
   //...
}

If you need that TemplateVersion has its own Id, then, to resolve your issue you could configure that relationship this way:

  modelBuilder.Entity<Template>()
        .HasRequired(template => template.CurrentVersion)
        .WithMany().HasForeignKey(t=>t.CurrentVersionId);

Upvotes: 1

Related Questions