How to extend relation between two entities without losing data?

asp.net-core c# entity-framework-core

Question

I'd like to extend existing relation between two entities without losing the data. That's ASP.NET Core 2.0 Web App.

I've got Cars and Navs (GPS sets). Specific Car could have a specific Nav and vice versa Specific Nav could be in a specific Car. However, Nav could be in a warehouse so it's not in any Car and specific Car could not have any Nav at the moment. Of course the specific Nav could be max in 1 car and specific Car could have max 1 Nav.

I've got relation between Navs and Cars. I'd like to add also relation between Cars and Navs to easily pull from Car level data about Nav system that's there at the moment (if any).

Now I have following setup:

public class Car
{
    public int ID { get; set; }
    public string ModelName { get; set; }
 //other properties
}
public class Nav
{
    public int ID { get; set; }
    public decimal ScreenSize { get; set; }
 //other properties
    public virtual Car Car { get; set; }
}

All I'd like to do is to add to Car class:

public virtual Nav Nav { get; set; }

But when I run Add-Migration it drops current relation so if I understand correctly I lose all data I have so far... That's what I get after AddMigration:

migrationBuilder.DropForeignKey(
    name: "FK_Navs_Cars_CarID",
    table: "Navs");

migrationBuilder.DropIndex(
    name: "IX_Navs_CarID",
    table: "Navs");

migrationBuilder.DropColumn(
    name: "CarID",
    table: "Navs");

migrationBuilder.AlterColumn<int>(
    name: "ID",
    table: "Navs",
    nullable: false,
    oldClrType: typeof(int))
    .OldAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn);

migrationBuilder.AddForeignKey(
    name: "FK_Navs_Cars_ID",
    table: "Navs",
    column: "ID",
    principalTable: "Cars",
    principalColumn: "ID",
    onDelete: ReferentialAction.Cascade);

What's the best way to maintain current relation & data and add relation from other side having both optional?

ADDED for clarification: With current relation I could easily pull data about Car from Nav level:

  var modelName = nav.Car != null ? nav.Car.ModelName : "";

I'd like to do the same other way too:

  var screenSize = car.Nav != null ? car.Nav.ScreenSize : 0;
1
1
7/19/2019 3:52:02 PM

Popular Answer

Before you added this property, EF was actually creating a one-to-many association. By adding this property, you're making it one-to-one. With a one to one, EF must define a principal end and dependent end (in other words, which one gets the foreign key). You can customize this, if you need to, but short of that, EF will make its own choice, and the situation here simply seems to be that it's choosing the opposite end from what you actually want. Therefore, you just need to add some fluent config to be explicit about what you want:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Car>()
        .HasOne(p => p.Nav)
        .WithOne(p => p.Car)
        .HasForeignKey<Nav>("CarID");
}
1
7/19/2019 6:41:25 PM


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