4

エンティティ フレームワークで外部キー関係を定義するのに問題があります。問題を示すために、コードを最小限にまとめました。

モデルは次のように定義されます。

    public class AccessControlList
{
    [Key] public int Id { get; set; }
    public string Name { get; set; }
}

public class ManagedFile
{
    [Key] public int Id { get; set; }
    public string Name { get; set; }
    public virtual AccessControlList AccessControl { get; set; }
}

public class ManagedFolder
{
    [Key] public int Id { get; set; }
    public string Name { get; set; }
    public virtual AccessControlList AccessControl { get; set; }
    public virtual ISet<ManagedFile> Files { get; private set; }

    public ManagedFolder()
    {
        Files = new HashSet<ManagedFile>();
    }
}

したがって、基本的には、ManagedFile または ManagedFolder エンティティのいずれかによって参照できる単一の AccessControl エンティティがあります。

外部キーが ManagedFile と ManagedFolder に追加されていることを確認するために、次の流暢なマッピングを追加しました。

protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();

        modelBuilder.Entity<ManagedFile>()
                    .HasRequired(mf => mf.AccessControl)
                    .WithRequiredDependent()
                    .Map(m => m.MapKey("AccessControlListId"));


        modelBuilder.Entity<ManagedFolder>()
                    .HasRequired(mf => mf.AccessControl)
                    .WithRequiredDependent()
                    .Map(m => m.MapKey("AccessControlListId"));

        base.OnModelCreating(modelBuilder);
    }

これにより、ManagedFile と ManagedFolder のそれぞれに外部キー AccessControlListId を使用して、期待どおりのデータベースが構築されます。

Entity Framework で作成されたスキーマ

私にはすべて問題ないように見えますが、データを挿入しようとすると、このコードで

using(var ctx = new MyContext())
{
    var mf = ctx.Folders.Add(new ManagedFolder {Name = "$/"});
    mf.AccessControl = new AccessControlList();

    var file = new ManagedFile {Name = "myfile.txt"};
    mf.Files.Add(file);
    file.AccessControl = new AccessControlList();

    ctx.SaveChanges();
}

それはエラーをスローします...

エラー

自分が何をしたのか理解できませんが、それは間違っていますか?

マッピングを理解しているので、EF は新しい AccessControlList エンティティを保存し、Id を使用して ManagedFolder または ManagedFile テーブルを書き込むことができます。

いつものように、提供されたヘルプに感謝します。

ありがとうアンディ

4

1 に答える 1

5

データベースが「期待どおり」に見えるのはなぜですか? 2 つの 1 対 1 の関係 ( ) を定義しようとしているようですが.HasRequired(...).WithRequiredDependent(...)、データベース内の関係は 1 対多です。

1 対 1 から 1 対多の関係が必要ですか? 後者の場合 (こちらの方が簡単です)、2 つのWithRequiredDependent()メソッドをに置き換えるだけWithMany()です。

1 対 1 が必要な場合は、別の外部キーを定義できませんAccessControlListId。共有主キーを使用する必要があります。つまり、従属の PK は同時に FK です。マッピングは次のようにする必要があります。

modelBuilder.Entity<ManagedFile>()
            .HasRequired(mf => mf.AccessControl)
            .WithRequiredDependent();
// the same for ManagedFolder

...なしでMapKey.

于 2012-06-20T15:55:37.150 に答える