Obi*_*Obi 3 c# entity-framework
我正在使用实体框架 codefirst 并且我有以下设计
public class Location
{
public int Id { get; set; }
public string Name { get; set; }
public bool IsDeleted { get; set; }
}
public class DelieryRate
{
public int Id { get; set; }
public int OriginId { get; set; }
public Location Origin { get; set; }
public int DestinationId { get; set; }
public Location Destination { get; set; }
public double Amount { get; set; }
public bool IsActive { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我不想在位置上定义关系。当我更新数据库时,它可以工作,但在运行种子代码时出现引用完整性错误。我尝试使用 Fluent api 进行配置,如下所示
modelBuilder.Entity<DeliveryRate>()
.HasRequired(e => e.Origin)
.WithOptional()
.WillCascadeOnDelete(false);
modelBuilder.Entity<DeliveryRate>()
.HasRequired(e => e.Destination)
.WithOptional()
.WillCascadeOnDelete(false);
Run Code Online (Sandbox Code Playgroud)
尝试更新数据库时出现以下错误
System.Data.Entity.Infrastruct.DbUpdateException:更新条目时发生错误。有关详细信息,请参阅内部异常。---> System.Data.UpdateException:更新条目时发生错误。有关详细信息,请参阅内部异常。---> System.Data.ConstraintException:违反引用完整性约束。依赖角色有多个具有不同值的主体。--- 内部异常堆栈跟踪结束 --- 在 System.Data.Mapping.Update.Internal.TableChangeProcessor.DiagnoseKeyCollision(UpdateCompiler 编译器、PropagatorResult 更改、CompositeKey key、PropagatorResult other) 在 System.Data.Mapping.Update.Internal。 TableChangeProcessor.ProcessKeys(UpdateCompiler编译器,列表
1 changes, Set1键)在System.Data.Mapping.Update.Internal.TableChangeProcessor.CompileCommands(ChangeNodechangeNode,UpdateCompiler编译器)在System.Data.Mapping.Update.Internal.UpdateTranslator.d__0.MoveNext()在 System.Linq.Enumerable.d__711.MoveNext() at System.Data.Mapping.Update.Internal.UpdateCommandOrderer..ctor(IEnumerable1 个命令,UpdateTranslator 翻译器) 在 System.Data.Mapping.Update.Internal.UpdateTranslator.ProduceCommands() 在 System.Data.Mapping.Update.Internal.UpdateTranslator.Update(IEntityStateManager stateManager, IEntityAdapter 适配器) at System.Data.EntityClient.EntityAdapter.Update(IEntityStateManagerEntityCache) at System.Data.Objects.ObjectContext.SaveChanges(SaveOptions options) at System.Data.Entity.Internal.InternalContext.SaveChanges() --- 内部异常结束堆栈跟踪 --- 在 System.Data.Entity.Internal.InternalContext.SaveChanges() 在 System.Data.Entity.Internal.LazyInternalContext.SaveChanges() 在 System.Data.Entity.DbContext.SaveChanges() 在 System.Data。 Entity.Migrations.DbMigrator.SeedDatabase() 在 System.Data.Entity.Migrations.Infrastruct.MigratorLoggingDecorator.SeedDatabase() 在 System.Data.Entity.Migrations.DbMigrator.Upgrade(IEnumerable1 pendingMigrations, String targetMigrationId, String lastMigrationId) at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.Upgrade(IEnumerable1endingMigrations,字符串 targetMigrationId,字符串 lastMigrationId) 在系统.Data.Entity.Migrations.DbMigrator.Update(String targetMigration) 在 System.Data.Entity.Migrations.Infrastruct.MigratorBase.Update(String targetMigration) 在 System.Data.Entity.Migrations.Design.ToolingFacade.UpdateRunner.RunCore()在 System.Data.Entity.Migrations.Design.ToolingFacade.BaseRunner.Run() 更新条目时发生错误。详细信息请参见内部异常
有没有更好的方法来建模位置和 DeliveryRate 之间的关系。我在使用 Fluent api 位时犯了一个错误吗
实体框架不支持具有单独外键的一对一关系。EF 使用共享主键映射您的模型,即DeliveryRate.Id和DeliveryRate.Origin.Id必须DeliveryRate.Destination.Id全部具有相同的值。他们可能没有在你的Seed方法中,这是异常的原因。
共享主键对您的模型没有用,因为您永远无法创建与DeliveryRate不同Destination的Origin.
您可以通过将两种关系建模为一对多来解决该问题:
modelBuilder.Entity<DeliveryRate>()
.HasRequired(e => e.Origin)
.WithMany()
.HasForeignKey(e => e.OriginId)
.WillCascadeOnDelete(false);
modelBuilder.Entity<DeliveryRate>()
.HasRequired(e => e.Destination)
.WithMany()
.HasForeignKey(e => e.DestinationId)
.WillCascadeOnDelete(false);
Run Code Online (Sandbox Code Playgroud)