我现在已经浪费了两天时间尝试解决这个问题,但还没有找到解决方案。
在我保存具有关系的实体的代码中,我在到达ctx.SaveChanges()
时收到此错误:
无法确定相关操作的有效排序。 由于外键约束,模型可能存在依赖关系 要求或商店生成的值。
Shipment.cs
[ForeignKey("ShipmentNumber")]
public int? DefaultShipmentNumber { get; set; }
public virtual ShipmentNumber ShipmentNumber { get; set; }
ShipmentNumber.cs
[Column("shipment_id")]
[ForeignKey("Shipment")]
public byte ShipmentId { get; set; }
public virtual Shipment Shipment { get; set; }
为避免循环引用,属于Shipment的ShipmentNumber可以为空(可选),而ShipmentNumber依赖于Shipment是必需的。
我首先创建一个货件,添加它然后将ShipmentNumber附加到它并将其添加到表中。
以下是流畅的API代码:
modelBuilder.Entity<Shipment>()
.HasOptional<ShipmentNumber>((shipment) => shipment.ShipmentNumber)
.WithMany();
装运有一个&#34; true&#34; ShipmentNumber,但许多ShipmentNumbers可以链接到同一个Shipment,因此WithMany()
调用(没有navigator属性的关系)。从理论上讲,这两种关系应该总是返回一个实体,但我知道EF不会在这里允许我1:1的关系,所以我使用了可选项。
这是实际的代码:
shipment = tracker.Shipment;
ctx.Shipments.Add(shipment);
shipment.ShipmentNumber = new ShipmentNumber { Number = tracker.ShipmentNumber };
ctx.ShipmentNumbers.Add(shipment.ShipmentNumber);
ctx.SaveChanges();
如果有人知道如何正确保存实体以及关系,请告诉我们。我此刻完全陷入困境。
答案 0 :(得分:2)
好吧,我不知道为什么你想要数据库中的1:n关系和模型中的1:0.1关系。
案例1
如果你想建立一个1:1的关系,你应该按如下方式声明你的模型:
public class Shipment
{
public int ShipmentId { get; set; }
//NO FK here
public virtual ShipmentNumber ShipmentNumber { get; set; }
}
public class ShipmentNumber
{
public int ShipmentId { get; set; } //ShipmentNumber PK is Also Shipment FK
public virtual Shipment Shipment { get; set; }
}
映射:
modelBuilder.Entity<Shipment>()
.HasKey(i => i.ShipmentId);
modelBuilder.Entity<ShipmentNumber>()
.HasKey(i => i.ShipmentId);
modelBuilder.Entity<Shipment>()
.HasRequired(i => i.ShipmentNumber)
.WithRequiredPrincipal(i => i.Shipment)
.WillCascadeOnDelete(false);
生成的迁移:
CreateTable(
"dbo.Shipments",
c => new
{
ShipmentId = c.Int(nullable: false, identity: true),
})
.PrimaryKey(t => t.ShipmentId);
CreateTable(
"dbo.ShipmentNumbers",
c => new
{
ShipmentId = c.Int(nullable: false),
})
.PrimaryKey(t => t.ShipmentId)
.ForeignKey("dbo.Shipments", t => t.ShipmentId)
.Index(t => t.ShipmentId);
案例2
如果你想建立一个1:n的关系:
public class Shipment
{
public int ShipmentId { get; set; }
public virtual ICollection<ShipmentNumber> ShipmentNumbers { get; set; }
}
public class ShipmentNumber
{
public int ShipmentNumberId { get; set; }
public int ShipmentId { get; set; }
public virtual Shipment Shipment { get; set; }
}
映射:
modelBuilder.Entity<Shipment>()
.HasKey(i => i.ShipmentId);
modelBuilder.Entity<ShipmentNumber>()
.HasKey(i => i.ShipmentNumberId);
modelBuilder.Entity<Shipment>()
.HasMany(i => i.ShipmentNumbers)
.WithRequired(i => i.Shipment)
.HasForeignKey(i => i.ShipmentId)
.WillCascadeOnDelete(false);
生成的迁移:
CreateTable(
"dbo.Shipments",
c => new
{
ShipmentId = c.Int(nullable: false, identity: true),
})
.PrimaryKey(t => t.ShipmentId);
CreateTable(
"dbo.ShipmentNumbers",
c => new
{
ShipmentNumberId = c.Int(nullable: false, identity: true),
ShipmentId = c.Int(nullable: false),
})
.PrimaryKey(t => t.ShipmentNumberId)
.ForeignKey("dbo.Shipments", t => t.ShipmentId)
.Index(t => t.ShipmentId);
另一个问题是您用于向数据库添加项目的代码。
ctx.Shipments.Add(shipment);
shipment.ShipmentNumber = new ShipmentNumber { Number = tracker.ShipmentNumber };
//this line is not necessary
ctx.ShipmentNumbers.Add(shipment.ShipmentNumber);
ctx.SaveChanges();
当您添加新的Shipment
时,如果需要,所有依赖对象都将插入数据库。