How to work with Navigation Property and non-standard keys?

c# entity-framework entity-framework-6 navigation-properties

Question

Let's say I have a 1:1 mapping between the following database tables.

Table dbo.Foo with PrimaryKey FooRowId
Table dbo.Bar with PrimaryKey BarRowId

There are no foreign keys on any table.

I defined models using EF as follows.

designing a Foo table

public class Foo
{
    [Key]
    public long FooRowId { get; set; }

    // Navigation
    public virtual Bar Bar { get; set; }
}

designing a bar table

public class Bar
{
    [Key]
    public long BarRowId { get; set; }

    // Navigation
    public virtual Foo Foo { get; set; }
}

This results in the following navigation property error.

Unable to determine the principal end of an association between the types 'MyOrg.Models.Foo' and 'MyOrg.Models.Bar'. The principal end of this association must be explicitly configured using either the relationship fluent API or data annotations.

The following standardisation of property names is one technique to address the issue.

On Foo

public class Foo
{
    [Key]
    [Column("FooRowId")]
    public long FooId { get; set; }

    // Navigation
    public virtual Bar Bar { get; set; }
}

On Bar

public class Bar
{
    [Key]
    [Column("BarRowId")]
    public long BarId { get; set; }

    // Navigation
    public virtual Foo Foo { get; set; }
}

However, I am required to maintain the original qualities.FooRowID and BarRowId . How can the navigation properties be made to function given this restriction?

1
1
1/11/2018 1:36:06 AM

Accepted Answer

Despite their seeming simplicity, attributes prevent you from using your classes in other databases.

Let's say you built a class called BillingAddress in accordance with your business's specifications (country maybe). This class should be used in two separate DbContexts, each of which should represent a different database. Primary keys for the BillingAddress in databases 1 and 2 are located in the columns "MyPrimaryKey" and "Id," respectively. That cannot be resolved using characteristics.

The database contains the names of the columns and tables as well as the relationships between them. Therefore, the DbContext needs to specify this. You may use the same class across various databases if you don't utilise attributes in the DbSet classes.

Consequently, let's create your table design in fluid Api.

See:

I provide examples for each of the three categories below:

  • Set up the table's primary key and table name.
  • Set up the following property: table name
  • Create table relationships, such as one-to-many

Remember that none of this is necessary if you use code first and keep to the entity framework's first-class coding practises. Entity Framework will be extremely good at identifying primary keys, foreign keys, and relations between tables as long as you follow these rules.

But if your tables are different, your DbContext has to have the following fluent API.

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
     // Configure entity table FOO:
     var entityFoo = modelBuilder.Entity<Foo>();

     // example: configure Name and primary key of foo table
     entityFoo.ToTable("MySpecialFooTable");
     entifyFoo.HasKey(foo => foo.FooRowId);

     // example: configure property Name is in column FooName:
     entityFoo.Property(foo => foo.Name).HasColumnName("MyFooName");

     // example: one-to-many relation between foo and bar
     // every Foo has zero or more Bars in property MyBars,
     // every Bar belongs to exactly one For in property MyFoo
     // using foreign key MyFooId:
     entityFoo.HasMany(foo => foo.MyBars)         // Foo has zero or more Bars in MyBars
              .WithRequired(bar => bar.MyFoo)     // every Bar belongs to one Foo
              .HasForeignKey(bar => bar.MyFooId); // using foreign key MyFooId
}
1
1/12/2018 7:29:29 AM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow