简体   繁体   中英

How to make One-To-One relationship with existing fields?

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)

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);
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM