0
votes

When migrating my data layer from Telerik to EF6 I had POCO naming issues. The EF model is "code first" generated from an existing database. Because i do not want to change the business layer, all migration/configuration needs to be done in the data layer. I also try to keep EF code generation from the database unchanged for future maintenance while using partial classes for keeping the legacy code intact.

So EF generates poco's with a FK reference like this:

public partial class MyPoco
{
        public Guid? MyForeignKeyDatabasePocoId { get; set; } /* Foreign key database column */

        public virtual MyForeignKeyDatabasePoco { get; set; } /* Navigation property MyForeignKeyDatabasePocoId database column */
}

This works out of the box since the naming convention is correct (generated) But now I like to add a navigation property based on the same database FK Id (used in the business layer),

public partial class MyPoco
{

        [ForeignKey("MyForeignKeyApplicationPoco", "MyForeignKeyDatabasePocoId")]  /* <- not possible, no constructor accepts two parms */
        public Guid? MyForeignKeyDatabasePocoId { get; set; }   /* Foreign key database column */

        public virtual MyForeignKeyDatabasePoco {get; set; }    /* Navigation property FK MyForeignKeyDatabasePocoId database column */

        public virtual MyForeignKeyApplicationPoco {get; set; } /* Navigation property FK MyForeignKeyDatabasePocoId database column */
}

I tried decorating the Id property with [ForeignKey("MyForeignKeyApplicationPoco")] but then it complains that "MyForeignKeyDatabasePoco" doesn't have a (foreign-)key. I can't set two foreignkey decorators to the id property either.

MyForeignKeyDatabasePoco and MyForeignKeyApplicationPoco are simular, they both exist in the model.

A) Is this possible? B) Should I change something in OnModelCreating(DbModelBuilder modelBuilder) when entity MyPoco is defined (or either or both of the fk poco's)? C) Should I just get rid of the generated nav property in favor of the legacy business property (not the preferred option btw)

Any help would be greatly appreciated.

Edit after bubi commented

Solved it with inheritance. First the database poco is abstracted and then the application poco inherits from then database poco

public abstract partial class MyForeignKeyDatabasePoco 
{
    /* EF generated code */ 
}

public partial class MyForeignKeyApplicationPoco : MyForeignKeyDatabasePoco 
{
    /* additional things todo */ 
}

public partial class MyPoco
{
        public Guid? MyForeignKeyDatabasePocoId { get; set; } /* Foreign key database column */

        public virtual MyForeignKeyApplicationPoco { get; set; } /* Navigation property to MyForeignKeyDatabasePocoId database column */
}

In the fluent model a DbSet< MyForeignKeyApplicationPoco > is added and in the fluent OnModelCreating(DbModelBuilder modelBuilder) modelBuilder.Entity< MyForeignKeyApplicationPoco >(); is added.

1

1 Answers

1
votes

Actually I think that it is not possible using attributes if you don't add a property with the foreign key field name. In that case you can use ForeignKey attribute setting the property as the foreign key.

Otherwise you can use fluent configuration (usually I use this way).

modelBuilder.Entity<OfficeAssignment>() 
        .HasRequired(t => t.PianoDiRientro)
        .WithMany(t => t.Rates)
        .Map(d => d.MapKey("IdPianoDiRientro"));

In this case is one to many relationship (one PianoDiRientro many Rates) and the foreign key column name is IdPianoDiRientro.