3

Enitity Frameworkコードファーストを使用しており、次のデザインを使用しています

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

場所の関係を定義したくありません。データベースを更新すると機能しますが、シードコードを実行すると参照整合性エラーが発生します。私は次のように流暢な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.TableChangeProcessor.CompileCommands(ChangeNode changeNode、UpdateCompilerコンパイラ)at System.Data.Mapping.Update.Internal.UpdateTranslator.d__0.MoveNext()at 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、IEntityAdapteradapter)、System.Data.EntityClient。 System.Data.Objects.ObjectContext.SaveChanges(SaveOptions options)のEntityAdapter.Update(IEntityStateManager entityCache)System.Data.Entity.Internal.InternalContext.SaveChanges()---内部例外スタックトレースの終了---システム。 Data.Entity.Internal.InternalContext.SaveChanges()at System.Data.Entity.Internal.LazyInternalContext.SaveChanges()at System.Data.Entity.DbContext.SaveChanges()at System.Data.Entity.Migrations.DbMigrator.SeedDatabase( )System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecoratorで。System.Data.Entity.Migrations.DbMigrator.Upgrade(IEnumerableのSeedDatabase()1 pendingMigrations, String targetMigrationId, String lastMigrationId) at System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator.Upgrade(IEnumerableSystem.Data.Entity.Migrations.DbMigrator.Update(String targetMigration)at System.Data.Entity.Migrations.Infrastructure.MigratorBase.Update(String targetMigration)atSystem.Data.Entityの1pendingMigrations、String targetMigrationId、String lastMigrationId) System.Data.Entity.Migrations.Design.ToolingFacade.BaseRunner.Run()のMigrations.Design.ToolingFacade.UpdateRunner.RunCore()エントリの更新中にエラーが発生しました。詳細については、内部例外を参照してください

LocationsとDeliveryRateの関係をモデル化するためのより良い方法はありますか。流暢なAPIビットを間違えていますか

4

2 に答える 2

5

個別の外部キーを使用した 1 対 1 のリレーションシップは、Entity Framework ではサポートされていません。EF はモデルを共有主キー、つまり にマップし、DeliveryRate.Idすべて同じ値を持つ必要がありますDeliveryRate.Origin.Id。おそらく、例外の原因であるメソッドに含まDeliveryRate.Destination.Idれていません。Seed

DeliveryRateとはDestination異なる を作成することはできないため、共有主キーはモデルには役に立ちませんOrigin

この問題は、2 つの関係を 1 対多としてモデル化することで解決できます。

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 に答える