3

EF を使用してデータベースにデータを保存する際に問題があります。通常、すべての CRUD 操作はプログラムの残りの部分で問題なく機能しますが、最近気付いたのですが、m:n の関係の場合、注意が必要な部分があります。

コードファーストアプローチでEF4.1を使用しています。私のクラスの興味深い部分は次のようになります。

public class Publication : IItem, IDataErrorInfo {

     ...

    [InverseProperty("Publications")]
    public virtual ICollection<Group> Groups{ get; set; }
}

public class Group : IItem, IDataErrorInfo {

     ...

    [InverseProperty("Groups")]
    public virtual ICollection<Publication> Groups{ get; set; }
}

データベースは次のように作成されます。

    public PublicationsDB() : base("PublicationDB") {
        this.Configuration.AutoDetectChangesEnabled = true;
    }

    public DbSet<Publication> Publications { get; set; }
    public DbSet<Software> Softwares { get; set; }
    public DbSet<Group> Group{ get; set; }

これは、出版物とグループの間に m:n の関係を作成することを目的としています。

最近、XML からデータをインポートしているとき、すべてがうまく機能します。SaveChanges() が呼び出された後、パブリケーションとグループのいずれかに ICollection が保存されます。以下の数行の同じ方法で、データベースからデータを取得しています(チェックのためだけに)。また、両方のエンティティに ICollection が入力されています。

そして、ここで問題が発生します。

データ操作のために別の関数を実行するときは、データベースからデータを掘り出し、次のことを行います。

  • 出版物のコレクションは問題ありません。エンティティのエールはICollection<Group>xml から適切に入力されています
  • しかし、グループのコレクションはかなりめちゃくちゃです。それらのほとんどはICollection<Publication>null に設定されています。

どのような問題が考えられますか? そのような行動は私にとって本当に奇妙です。最後になりましたが、からのコレクションの削除はDBSet<Groups>決定論的ではありません。つまり、グループ A とグループ B を考慮すると、プログラムの 1 回の実行でA.ICollection = null and B.ICollection.Count =1 (which is by the way wrong)は異なるのに対し、別の実行では異なるということです。つまり、A.ICollection = null and B.ICollection = null (which is also wrong)

何か案は?

コードを最初に DB に構築するときにモデルがめちゃくちゃになる? フレームワークエラーまたは奇妙な内部フレームワーク最適化? それとも私はただのお尻の穴ですか?:)

また、新しいエンティティを内部に配置して関係を変更することも考えていました。つまり、Publication (m):(n) Groupのようなものに移行しますがPublication (m):(1) NewEntityRelation (n):1 Group、別の解決策がある場合は、別の解決策を希望します。

返信ありがとうございます。

4

1 に答える 1

3

私が間違っていない限り、InverseProperty 属性は、EF が関係の一方の側と他方の側をペアにするのに役立ちますが、それがどのような関係であるかについて EF に何も伝えません。「m:n」の関係を作成したいと言うとき、それは「多対多」を意味すると思いますが、EF が常にそれを正しく理解しているとは限りません。OnModelCreating メソッドをオーバーライドして、多対多の関係のマッピングを手動で指定する習慣をつけました。以下は、サンプル コード スニペットです。

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<User>()
            .HasMany(a => a.Roles)
            .WithMany(r => r.Users)
            .Map(config =>
            {
                config.ToTable("UserRoles");
                config.MapLeftKey("UserId");
                config.MapRightKey("RoleId");
            });
    }

上記のスニペットは、システム内のユーザーとその役割の間の多対多の関係を定義するために使用されている私のプロジェクトから取得したものです。このようにして、EF は、どのような関係、データベース内の中間テーブルの名前、または一方を他方にマップするために使用されるキーについて "混乱" することはありません。関係の片側だけに問題が見られる理由はわかりませんが、EF があなたが何をしようとしているのかを完全に把握できていないためだと思います。

于 2012-06-08T13:14:30.640 に答える