3

Entity Framework 5 を使用して、多対多の関係を持つ単純な挿入を試みています。

次のように2つのPOCOクラスがあります。

public class Category
{
    public virtual string Title { get; set; }
    public virtual DateTime EntryDate { get; set; }
    public virtual DateTime LastUpdated { get; set; }
    public virtual ICollection<Article> Articles { get; set; }
}

public class Article
{
    public virtual string Title { get; set; }
    public virtual string Content { get; set; }
    public virtual DateTime EntryDate { get; set; }
    public virtual DateTime LastUpdated { get; set; }
    public virtual ICollection<Category> Categories { get; set; }
}

そして、次の流暢な API マッピング コード...

public class CategoryMap : EntityTypeConfiguration<Category>
{
    public CategoryMap()
    {
        this.ToTable("Categories");
        this.HasKey(x => x.ID);

        this.Property(x => x.Title).IsRequired().HasMaxLength(255);
    }
}

public class ArticleMap : EntityTypeConfiguration<Article>
{
    public ArticleMap()
    {
        this.ToTable("Articles");
        this.HasKey(x => x.ID);

        this.HasMany(x => x.Categories)
            .WithMany(x => x.Articles)
            .Map(x =>
            {
                x.ToTable("MapArticleCats");
                x.MapLeftKey("CategoryID");
                x.MapRightKey("ArticleID");
            });

        this.Property(x => x.Title).IsRequired().HasMaxLength(255);
        this.Property(x => x.Content).IsRequired().HasMaxLength(4000);
    }
}

次に、エンティティ フレームワークは、Category テーブルと Article テーブルの両方を生成し、その詳細が ArticleMap コード (MapArticleCats) で指定された 3 番目のマッピング テーブルと共に生成します。SQL Server では次のようになります。

記事 ID - int
カテゴリ ID -int

次のコード (数行の追加または取得) は、コントローラーの記事にカテゴリを追加します。

IEnumerable<Category> GetCats = CategoryRepository.GetAll();

//DO SOME CODE TO FIGURE WHICH CATEGORIES I NEED.
IEnumerable<Category> Categories = InferCategoriesFromPostedData(Model.Categories, GetCats);

foreach (Category c in Categories)
{
    Article.Categories.Add(c);
}

これにより、挿入時に奇妙な動作が発生するようです。新しいカテゴリをカテゴリ テーブルに挿入し (DUPLICATE)、新しく作成された CategoryID (元の ID の代わりに) と正しい ArticleID を MapArticleCats テーブルに挿入します。

誰かが私が間違っているところを見ることができますか?

4

3 に答える 3

4

この記事 (および以前の記事は... 非常に有罪) を送信する前に、私がすべきだったことは、StackOverflow を検索して、もう少し徹底的に調べることでした。

ここで私の問題に対する答えを見つけました

起こっていたことは、上記のコードとはまったく関係がありませんでした。これは、基本的に 2 つのデータ コンテキストをコントローラーに挿入し (1 つは記事リポジトリに、もう 1 つはカテゴリ リポジトリに)、重複したレコードを作成していたためです。

================================================== ================================
重要な編集
================ ================================================== ================

私の答えを詳しく説明するために...

上記の修正を行った後でも、ナビゲーション プロパティ (カテゴリ) を更新できないという当初の問題は解決しませんでした。これに対する修正は以下にあります...

AsNoTracking() を使用してエンティティ (記事) をモデル バインディングしていましたが、メイン エンティティ自体を更新するだけでナビゲーション プロパティを操作できない場合はこれで問題ありません。たとえば、私の場合、記事からカテゴリを追加/削除します。

エンティティをコンテキストから切り離すことで同様の方法を試したので、これは私を少し苦しめましたが、最終的にはどちらの方法でも、ナビゲーション プロパティを操作できないという同じ問題が発生しました。

これを修正する方法は、エンティティを通常どおりバインド/選択するだけでモデル化することでした。AsNoTracking() なし、デタッチなし。エンティティをコンテキストに戻すときは、次のコードを使用します...

    public bool Attach(T entity)
    {
        T original = _dbSet.Find(entity.ID);
        _dbContext.Entry(original).CurrentValues.SetValues(entity);
        _dbContext.Entry(original).State = EntityState.Modified;

        return this.Commit();
    }

このようにして、AsNoTracking/Detaching ゴミを実行せずに選択することができ、問題なく更新されます。これは私にとっては問題ありません。データベースへの余分な移動を少し不快に感じる人もいるかもしれませんが、そのすべての悲しみのために、私にはぴったりです。

于 2012-11-05T12:16:44.010 に答える