2

ItemPrice クラスと ItemPriceHistory クラスの間には 1 対多の関係があります。私のマッピングは以下のとおりです。

public class ItemPrice 
{
    public long ID {get; set;}
    public List<ItemPriceHistory> ItemPriceHistories { get; set; }

    public ItemPrice()
    {
       ItemPriceHistories = new List<ItemPriceHistory>();
    }
}

public class ItemPriceHistory
{
    public ItemPrice ItemPrice { get; set; }
    public long ID {get; set;}
    public bool IsCurrent { get; set; }
}


modelBuilder.Entity<ItemPriceHistory>()
            .HasRequired(h => h.ItemPrice)
            .WithMany(p => p.ItemPriceHistories)
            .Map(h => h.MapKey("ItemPrice_ID"));

以前の ItemPriceHistory エントリを更新して、新しい ItemPriceHistory エントリを追加しようとしています。

    var dbItemPrice = repo.Std.Get<ItemPrice>()
                                    .SingleOrDefault(c => c.ID == id);                

            if (dbItemPrice == null)
            {
                return Request.CreateResponse(HttpStatusCode.NotFound);
            }                

            //query for matching ItemPriceHistory
            var dbPriceHistories = repo.Std.Get<ItemPriceHistory>()
                                    .Include(h=>h.ItemPrice, repo.Std)
                                    .Where(h => h.ItemPrice.ID == ItemPrice.ID)
                                    .OrderByDescending(h => h.ModifiedDate);

            #region new history entry

            var newHistoryEntry = new ItemPriceHistory();
            newHistoryEntry.IsCurrent = true;
            newHistoryEntry.ItemPrice = dbItemPrice;

            //copy the current pirce list and update it with new history entry
            var currentPriceHistoryList = dbPriceHistories.ToList();
            currentPriceHistoryList.ForEach(h => { h.IsCurrent = false; });
            currentPriceHistoryList.Add(newHistoryEntry);

            //new price list
            var newHistoryList = new List<ItemPriceHistory>();
            currentPriceHistoryList.ForEach(h => newHistoryList.Add(new ItemPriceHistory
                                            {
                                                ItemPrice = h.ItemPrice,
                                                IsCurrent = h.IsCurrent,
                                            }
                                    ));
            #endregion

            //delete current price histories
            dbItemPrice.ItemPriceHistories.Clear(); 


            // add histories to database
            newHistoryList.ForEach(h => dbItemPrice.ItemPriceHistories.Add(h));

            Context.SaveChanges();

SaveChanges() を呼び出すと、次のエラーが発生します。

{「関係の外部キー プロパティを公開していないエンティティを保存中にエラーが発生しました。単一のエンティティを例外のソースとして識別できないため、EntityEntries プロパティは null を返します。保存中の例外の処理は、公開することで簡単に行うことができます。エンティティ タイプの外部キー プロパティ。詳細については、InnerException を参照してください。"}

InnerException: {「「ItemPriceHistory_ItemPrice」AssociationSet からの関係は「削除済み」状態にあります。多重度の制約がある場合、対応する「ItemPriceHistory_ItemPrice_Source」も「削除済み」状態でなければなりません。"}

を削除したくありませんItemPrice_SourceItemPriceHistories現在を削除して以前を更新ItemPriceHistoriesし、新しいItemPriceHistoryエントリを追加したいだけです。ItemPriceHistory新しいエントリとともにエントリを安全に更新するにはどうすればよいItemPriceHistoryですか?

ありがとう!

4

2 に答える 2

0

STD ジェネリック リポジトリ クラスに適合するはずの例を使用します。このパターンを使用しているようです。

次のようなことを試しましたか

 public virtual IQueryable<T> GetList(Expression<Func<T, bool>> predicate, bool withTracking = false)
    {
        if (withTracking)
            return QuerySet.Where(predicate);
        return QuerySet.Where(predicate).AsNoTracking();
    }


//    then
var iph_list = RepItemPriceHist.GetList(h=>h.ItemPrice.Id == VarID)

 //  psuedo code... foreach history entity entitity.Iscurrent = false;

そのため、これらのエンティティはステートマネージャーによって変更および管理される必要があります。新しいエントリを追加します....

// add histories to database
          newHistoryList.ForEach(h => dbItemPrice.ItemPriceHistories.Add(h));
 Context.SaveChanges();

コレクションをクリアする必要がある理由がわかりませんでした。既存のレコードを更新して新しいレコードを追加していませんか? 幸運を

于 2012-12-29T11:07:08.107 に答える
0

すべての currentItemPrice を含めてロードし、それらの履歴のフラグを にItemPriceHistories設定して新しい履歴を追加することはできませんか? 変更追跡は現在の履歴を更新し、新しい履歴をデータベースに挿入する必要があります。IsCurrentfalseIsCurrent = true

var dbItemPrice = repo.Std.Get<ItemPrice>()
    .Include(i => i.ItemPriceHistories, repo.Std)
    .SingleOrDefault(i => i.ID == id);                

if (dbItemPrice == null)
    return Request.CreateResponse(HttpStatusCode.NotFound);

foreach (var history in dbItemPrice.ItemPriceHistories)
    history.IsCurrent = false;

dbItemPrice.ItemPriceHistories.Add(new ItemPriceHistory { IsCurrent = true });

Context.SaveChanges();
于 2012-12-29T15:17:40.020 に答える