依赖角色有多个具有不同值的主体

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__71 1.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(IEnumerable 1 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 位时犯了一个错误吗

Sla*_*uma 5

实体框架不支持具有单独外键的一对一关系。EF 使用共享主键映射您的模型,即DeliveryRate.IdDeliveryRate.Origin.Id必须DeliveryRate.Destination.Id全部具有相同的值。他们可能没有在你的Seed方法中,这是异常的原因。

共享主键对您的模型没有用,因为您永远无法创建与DeliveryRate不同DestinationOrigin.

您可以通过将两种关系建模为一对多来解决该问题:

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)