10

Entity Framework Code First 4.3.1を使用すると、多重度が1対1の関係を作成できます。つまり、関係の両端に1つのエンティティがあります。

1対1の関係を必須-必須または必須-オプション^に構成することができます。ただし、2つを切り替えても、次の点で違いは見られません。

  • 生成されたデータベーススキーマ。SQLServer2008をターゲットにしています。
  • EFの実行時の動作。

そのため、関係がrequired-requiredとして構成されているにもかかわらず、対応するRequiredDependentAsレコードなしでRequiredPrincipalAsレコードを作成できます。これは、HasRequired(...)のドキュメントと矛盾しているようです。

このエンティティタイプから必要な関係を構成します。この関係が指定されていない限り、エンティティタイプのインスタンスをデータベースに保存することはできません。データベース内の外部キーはnull不可になります。

http://msdn.microsoft.com/en-us/library/gg671317

必須-必須の関係エンティティ:

public class RequiredPrincipalA
{
    public int Id { get; set; }
    public virtual RequiredDependentA DependentA { get; set; }
}

public class RequiredDependentA
{
    public int Id { get; set; }
    public virtual RequiredPrincipalA PrincipalA { get; set; }
}

必須-オプションの関係エンティティ:

public class RequiredPrincipalB
{
    public int Id { get; set; }
    public virtual OptionalDependentB DependentB { get; set; }
}

public class OptionalDependentB
{
    public int Id { get; set; }
    public virtual RequiredPrincipalB PrincipalB { get; set; }
}

DbContextとモデル構成:

public class AppContext : DbContext
{
    public DbSet<RequiredPrincipalA> PrincipalAs { get; set; }
    public DbSet<RequiredDependentA> DependentAs { get; set; }

    public DbSet<RequiredPrincipalB> PrincipalBs { get; set; }
    public DbSet<OptionalDependentB> DependentBs { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<RequiredPrincipalA>()
            .HasRequired(o => o.DependentA)
            .WithRequiredPrincipal(o => o.PrincipalA);

        modelBuilder.Entity<RequiredPrincipalB>()
            .HasOptional(o => o.DependentB)
            .WithRequired(o => o.PrincipalB);
    }
}

テストコード:

Database.SetInitializer(new DropCreateDatabaseAlways<AppContext>());

using (var ctx = new AppContext())
{
    ctx.Database.Initialize(force: false);

    ctx.PrincipalAs.Add(new RequiredPrincipalA());
    ctx.PrincipalBs.Add(new RequiredPrincipalB());

    ctx.SaveChanges();
}

RequiredPrincipalA.DependentAおよびRequiredDependentA.PrincipalAのナビゲーションプロパティに[Required]データ属性を追加できることを認識しています。これにより、EF検証が発生し、上記のシナリオが防止されます。ただし、既存のエンティティを更新するときにナビゲーションプロパティが入力されていることも検証するため、これは実行したくありません。つまり、アプリケーションは、更新のたびに、関係のもう一方の端にあるエンティティをプリフェッチする必要があります。

required-requiredrequired-optionalの関係を変更しただけで、EFの動作に違いが見られないのはなぜですか?

^オプション-オプションもサポートされていることに注意してくださいが、これは私の質問の一部ではありません。オプションとオプションの関係が構成されている場合、生成されるデータベーススキーマと実行時の動作には明らかな違いがあります。

4

3 に答える 3

13

この場合、required-requiredが許可される理由はわかりませんが、リレーションが主キーに基づいて構築されているため、データベースに存在できません。必須-必須とは、関連するBが存在しない場合はAを挿入できず、関連するAが存在しない場合はBを挿入できないことを意味します=>AもBも挿入できません。

データベースリレーションには常にプリンシパルと依存エンティティがあります。プリンシパルは常に依存なしで存在できます。

EFでの実際の必須-必須は、AとBの両方が同じテーブルにマップされている場合(テーブル分割)にのみ達成できます。そのような場合、両方が単一の挿入コマンドで挿入されるためです。

于 2012-06-27T11:10:51.170 に答える
5

本当の答えではありませんが、コメントに収まる以上に言いたいことがあります。しかし、あなたが知っている、私は900ページの本を書いています...それは私が転がる方法です。:)

奇妙なことに、流暢な構成はデータアノテーションと同じように動作することを期待し、それが実行されていないことに混乱しています。(私はRowan Millerにこのスレッドへのリンクをpingして、フィードバックを取得しました。)そして、私が意味する動作は、SaveChanges中に制約を検証することです。

データベース側では、私はLadislavを使用しています。モデルでは、EFは関連するエンティティのキ​​ーを使用して1:1を定義します。ただし、データベースでは、両方のテーブルにFKを含めることはできないため、データベース内の依存テーブルのみが、PKがプリンシパルテーブル内の既存のPKにマップされるという制約を必要とします。

そして最後に、完全グラフを常に処理するつもりがない場合に、EFに関係を強制させたくない理由を理解しました。1:1の関係は、EF関係のマッピングの中で最も混乱していると思います。私は常に、ルールと物事がどのように機能するかを思い出させるために戻る必要があることに気付きます。

于 2012-06-29T21:08:07.013 に答える
0

古い質問。しかし、EF6はまだ使用されており、.Net標準でも利用可能でありこの問題は非常に厄介な問題になる可能性があるため、他の回答では見つけられなかった点について言及する価値があると思います。

両方とも同じデータベーススキーマと同じランタイム動作HasRequired - WithRequiredPrincipalを生成することは事実です。HasOptional - WithRequiredつまり、両方のマッピングを使用して、依存エンティティなしでプリンシパルを保存し、後で依存エンティティを削除することができます。についてはこれだけですHasRequired

ただし、エンティティを作成するときにEFに必要な関係を検証させる方法があります。これは、[Required]属性を追加するだけです。

public class RequiredPrincipalA
{
    public int Id { get; set; }

    [Required] // <== here
    public virtual RequiredDependentA DependentA { get; set; }
}

public class RequiredDependentA
{
    public int Id { get; set; }
    public virtual RequiredPrincipalA PrincipalA { get; set; }
}

前述のように、エンティティを作成する場合のみ。RequiredPrincipalA.RequiredDependentA = null正常に設定および保存することは引き続き可能です。しかし、幸いなことに、コードで発生する可能性は、必要な依存関係を設定するのを忘れるよりもはるかに低いと思います。

于 2021-01-15T22:15:45.603 に答える