【问题标题】:How to extend relation between two entities without losing data?如何在不丢失数据的情况下扩展两个实体之间的关系?
【发布时间】:2019-07-19 14:40:01
【问题描述】:

我想在不丢失数据的情况下扩展两个实体之间的现有关系。那就是 ASP.NET Core 2.0 Web 应用程序。

我有CarsNavs(GPS 装置)。特定的Car 可以有一个特定的Nav,反之亦然特定的Nav 可以在特定的汽车中。但是,Nav 可能在仓库中,因此它不在任何 Car 中,并且特定 Car 目前不能有任何 Nav。当然,特定的Nav 最多可以在 1 辆汽车中,特定的汽车最多可以有 1 个导航。

我在NavsCars 之间建立了关系。我还想添加 Cars 和 Navs 之间的关系,以便轻松地从 Car 级别的数据中提取有关 Nav 目前存在的系统(如果有的话)。

现在我有以下设置:

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

我想做的就是添加到Car 类:

public virtual Nav Nav { get; set; }

但是当我运行Add-Migration 时,它会降低当前关系,所以如果我理解正确,我会丢失我目前拥有的所有数据......这就是我在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);

维护当前关系和数据并从另一方添加关系的最佳方式是什么?

添加说明: 使用当前关系,我可以轻松地从 Nav 级别提取有关 Car 的数据:

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

我也想以其他方式做同样的事情:

  var screenSize = car.Nav != null ? car.Nav.ScreenSize : 0;

【问题讨论】:

  • 请同时显示您打算制作的模型+新旧映射。
  • @GertArnold 如前所述,我想稍微修改 Car 类,添加:public virtual Nav Nav { get; set; },但是当我这样做时,Add-Migration 会丢弃当前 FK...现在我可以轻松从导航级别提取 Car 的数据,例如:var modelName = nav.Car != null ? nav.Car.ModelName : ""。我也想以其他方式这样做:var screenSize = car.Nav != null ? car.Nav.ScreenSize : 0。希望它能澄清主题。

标签: c# asp.net-core entity-framework-core


【解决方案1】:

在添加此属性之前,EF 实际上是在创建一对多关联。通过添加此属性,您将实现一对一。在一对一的情况下,EF 必须定义一个主端和从属端(换句话说,哪一个获得外键)。如果需要,您可以自定义它,但如果没有,EF 将做出自己的选择,而这里的情况似乎只是它选择了与您实际想要的相反的一端。因此,您只需要添加一些流畅的配置来明确您想要什么:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Car>()
        .HasOne(p => p.Nav)
        .WithOne(p => p.Car)
        .HasForeignKey<Nav>("CarID");
}

【讨论】:

  • 谢谢回答。不幸的是,它并没有解决问题。 FK 仍然被删除,因为 Add-Migration 想要首先将列更改为不可为空。这是结果migrationBuilder.DropForeignKey(name: "FK_Navs_Cars_CarID", table: "Navs"); migrationBuilder.AlterColumn&lt;int&gt;(name: "CarID", table: "Navs", nullable: false, oldClrType: typeof(int), oldNullable: true); migrationBuilder.AddForeignKey(name: "FK_Navs_Cars_CarID", table: "Navs", column: "CarID", principalTable: "Cars", principalColumn: "ID", onDelete: ReferentialAction.Cascade); 我应该先更改列并将空值更改为 0 吗?
  • 跟进上面的评论:或者也许'保存以运行迁移而不丢失当前关系?它会暂时放弃 FK,自行将空值更改为 0,然后使用现有 CarID 重新创建关系,还是删除所有现有 CarID?
猜你喜欢
  • 2021-04-06
  • 1970-01-01
  • 1970-01-01
  • 2019-11-13
  • 2012-08-17
  • 1970-01-01
  • 1970-01-01
  • 2017-04-07
相关资源
最近更新 更多