1

I have 3 entities:

  • Foo
  • Bar
  • UniqueFooBar

Foo and Bar are entities as follows:

public class Bar {

   public int Id {get; set;}

   // inverse nav property
   public virtual UniqueFooBar UniqueFooBar {get; set;}

}

public class Foo {

   public string Name {get; set;}

   // inverse nav property
   public virtual UniqueFooBar UniqueFooBar {get; set;}
}

And UniqueFooBar is a lookup as follows:

public class UniqueFooBar {

   public string FooName {get; set;}
   public int BarId {get; set;}

   // nav properties
   public virtual Foo Foo {get; set;}
   public virtual Bar Bar {get; set;}

}

With constraints that:

  • Foo is unique
  • there is a one-to-one relationship to both Foo and Bar
  • Foo Name is the PK

    The fluent API is as follows:

    class UniqueFooBarConfiguration : EntityTypeConfiguration<UniqueFooBar> {
        public UniqueFooBarConfiguration() {
            // Define the tablename and schema
            Map(entity => entity.ToTable("UniqueFooBars"));
    
            //// Define non-conventional key
            HasKey(fooBar => fooBar.FooName);
    
            // Define FKs -  1-to-1
            HasRequired(fooBar => fooBar.Foo)
                .WithRequiredPrincipal(foo => foo.UniqueFooBar)
                .Map(key => key.MapKey("FooName"));
            HasRequired(fooBar => fooBar.Bar)
                .WithRequiredPrincipal(bar => bar.UniqueFooBar)
                .Map(key => key.MapKey("BarId"));
            // --------------------------------
    
        }
    
    }
    

What is happening is that FooName is being added to the Foo table and BarId is being added tot he Bar table.

If, in the fluent API configuration for UniqueFooBar, I instead try to use Foo's "Name" property then there is an error that the field already exists. Same happens if I try to use Bar's "Id" property.

How can I configure UniqueFooBar to have FKs to Foo.Name and Bar.Id as one-to-one relationships?

Update

  • Neither Foo nor Bar has constraint or requirement of a UniqueFooBar.
  • A UniqueFooBar record requires a FooName and a BarId

This does not appear to be the same as How to declare one to one relationship using Entity Framework 4 Code First (POCO)

Community
  • 1
  • 1
IAbstract
  • 19,551
  • 15
  • 98
  • 146
  • 1
    possible duplicate of [How to declare one to one relationship using Entity Framework 4 Code First (POCO)](http://stackoverflow.com/questions/3622572/how-to-declare-one-to-one-relationship-using-entity-framework-4-code-first-poco) – User Aug 30 '13 at 19:56
  • Have you read http://stackoverflow.com/questions/15549680/how-do-i-establish-a-one-to-one-relationship-with-entity-framework-code-first ? – Paul Zahra Sep 03 '13 at 08:08
  • @PaulZahra if you can summarize the link in that accepted answer, then I'll accept it: http://blog.bennymichielsen.be/2011/06/02/entity-framework-4-1-one-to-one-mapping/ Because a bounty is attached, a bit of summary would be nice with replication of the relevant code snippets. – IAbstract Sep 03 '13 at 18:04

1 Answers1

1

Taken from here, below is an example of how you can achieve one to one mapping between two entities, extrapolate this for a link table, adding HasRequired as required.

It is possible to specify WithRequiredPrincipal without a lambda, which allows you to exclude a navigation property and still get a proper one to one mapping.

Within an override of the OnModelCreating method you define your relationships by using the DBModelBuilder parameter.

public class Customer
{
    public Customer()
    {
        Address = new Address();
    }

    public Guid Id { get; set; }
    public string Name { get; set; }
    public Address Address { get; set; }
}

public class Address
{
    public Guid Id { get; set; }
    public string City { get; set; }
    public string Country { get; set; }
    public string Street { get; set; }
}

public  class  CustomerContext : DbContext
{
    public IDbSet<Customer> Customers { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
         modelBuilder.Entity<Customer>()
                .HasRequired(x => x.Address)
                .WithRequiredPrincipal();
         base.OnModelCreating(modelBuilder);
    }
}
Paul Zahra
  • 9,522
  • 8
  • 54
  • 76
  • Thanks for the extra bit of explanation ... I think I understand why *things just didn't work* before. If I understand correctly, because I have a forward nav property, I don't need to supply a lambda in the `WithRequiredPrincipal` method; this is where there seems to be some confusion. – IAbstract Sep 04 '13 at 18:27