3

我正在使用实体框架 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; }
}

我不想在 Location 上定义关系。当我更新数据库时,它可以工作,但是当我运行我的种子代码时出现引用完整性错误。我尝试使用 fluent api 配置它,如下所示

modelBuilder.Entity<DeliveryRate>()
            .HasRequired(e => e.Origin)
            .WithOptional()
            .WillCascadeOnDelete(false);

modelBuilder.Entity<DeliveryRate>()
            .HasRequired(e => e.Destination)
            .WithOptional()
            .WillCascadeOnDelete(false);

尝试更新数据库时出现以下错误

System.Data.Entity.Infrastructure.DbUpdateException:更新条目时出错。有关详细信息,请参阅内部异常。---> System.Data.UpdateException:更新条目时出错。有关详细信息,请参阅内部异常。---> System.Data.ConstraintException:违反参照完整性约束。一个从属角色有多个具有不同值的主体。--- 内部异常堆栈跟踪结束 --- System.Data.Mapping.Update.Internal.TableChangeProcessor.DiagnoseKeyCollision(UpdateCompiler 编译器,PropagatorResult 更改,CompositeKey 键,PropagatorResult 其他)在 System.Data.Mapping.Update.Internal。 TableChangeProcessor.ProcessKeys(UpdateCompiler 编译器,列表1 changes, Set1 个键)在 System.Data.Mapping.Update.Internal.UpdateTranslator.d__0.MoveNext() 在 System.Linq.Enumerable.d__71 的 System.Data.Mapping.Update.Internal.TableChangeProcessor.CompileCommands(ChangeNode changeNode, UpdateCompiler 编译器)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 adapter) 在 System.Data.EntityClient。 EntityAdapter.Update(IEntityStateManager entityCache) 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.Infrastructure.MigratorLoggingDecorator。System.Data.Entity.Migrations.DbMigrator.Upgrade 上的 SeedDatabase()(IEnumerable1 pendingMigrations, String targetMigrationId, String lastMigrationId) at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.Upgrade(IEnumerableSystem.Data.Entity.Migrations.Infrastructure.MigratorBase.Update(String targetMigration) 处 System.Data.Entity.Migrations.DbMigrator.Update(String targetMigration) 处的 1 个 pendingMigrations、String targetMigrationId、String lastMigrationId)。 System.Data.Entity.Migrations.Design.ToolingFacade.BaseRunner.Run() 处的 Migrations.Design.ToolingFacade.UpdateRunner.RunCore() 更新条目时出错。有关详细信息,请参阅内部异常

有没有更好的方法来模拟 Locations 和 DeliveryRate 之间的关系。我在流利的 api 位上犯了一个错误吗

4

2 回答 2

5

实体框架不支持具有单独外键的一对一关系。EF 使用共享主键映射您的模型,也就是说DeliveryRate.IdDeliveryRate.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);
于 2013-03-18T18:51:07.767 回答
0

当关系映射出错时会抛出此错误,它可能将两个关系映射到同一个外键属性:

modelBuilder.Entity<TipOrder>().HasRequired(c => c.Tip).WithMany(x => x.TipOrders).HasForeignKey(x => x.TipId).WillCascadeOnDelete(false);
modelBuilder.Entity<TipOrder>().HasRequired(c => c.Order).WithMany(x => x.TipOrders).HasForeignKey(x => x.TipId).WillCascadeOnDelete(false);

两者都意外地映射到 TipId。

于 2018-07-27T10:17:05.630 回答