0

ここでちょっとした問題があります。私は多くの SO スレッドを読みましたが、答えが見つかりませんでした。

Code First EFを利用して、データアクセスに切断されたリポジトリパターンを使用しています。

POCO:

public class LineItem
{
    [Key]
    public int Id { get; set; }
    public string Name { get; set; }
    public ICollection<LineItemCategoryMap> LineItemCategoryMaps { get; set; }
}

public class LineItemCategoryMap
{
    [Key]
    public int Id { get; set; }

    [ForeignKey("LineItem")]
    public int LineItemId { get; set; }
    public LineItem LineItem { get; set; }

    [ForeignKey("Category")]
    public int CategoryId { get; set; }
    public Category Category { get; set; }
}

データ アクセス コード (更新):

public void Update(LineItem lineItem)
{
    using (var db = new DBContext())
    {
        db.LineItems.Attach(lineItem);
        db.Entry(lineItem).State = EntityState.Modified;
        db.SaveChanges();
    }
}

単一の LineItemCategoryMap がある場合、更新は機能します。ただし、同じ LineItemID を持つ 2 つのアイテムがある場合、「同じキーを持つオブジェクトが ObjectStateManager に既に存在します」という例外が発生します。投げられます。

複数のマップ オブジェクトを含む LineItem の作成は 100% 機能します

ご覧のとおり、LineItem は複数回アタッチしようとしています。LineItem を再利用するべきではありませんか?

4

1 に答える 1

0

@tschmit007 に感謝します。私が地図を読み込もうとしていたことに気づきました。

LineItemCategoryMap の ID を削除し、複合キーを追加することでこれを解決しました。

public class LineItemCategoryMap
{
    [Key, Column(Order = 0)]
    [ForeignKey("LineItem")]
    public int LineItemId { get; set; }
    public LineItem LineItem { get; set; }

    [Key, Column(Order = 1)]
    [ForeignKey("Category")]
    public int CategoryId { get; set; }
    public Category Category { get; set; }
}

残念ながら、更新コードは、エンティティをマークしてもナビゲーション プロパティ (つまり関係) ではなく、スカラーおよび複雑なプロパティのみが保存されるため、少し不衛生になります。 https://stackoverflow.com/a/14102487/101662

var lineItemToUpdate = (from obj in db.LineItems.Include("LineItemCategoryMaps")
                                             where obj.Id == lineItem.Id
                                             select obj).First();

lineItemToUpdate.LineItemCategoryMaps = lineItem.LineItemCategoryMaps;
lineItemToUpdate.LineItemDepartmentMaps = lineItem.LineItemDepartmentMaps;

db.Entry(lineItemToUpdate).CurrentValues.SetValues(lineItem);

db.SaveChanges();

これを機能させる唯一の方法は、コンテキストのスコープでオブジェクトをフェッチしてから、ナビゲーション プロパティを設定することです。

これを行うためのよりクリーンな方法を知っている人はいますか? おそらく追加のデータベース呼び出しなしで。

ナビゲーション プロパティを変更できるようにしたいです。

于 2013-04-15T13:22:49.217 に答える