【问题标题】:how can I update children and insert new child in one to many relationship in EF如何在 EF 中以一对多关系更新孩子并插入新孩子
【发布时间】:2012-12-28 23:36:03
【问题描述】:

我在 ItemPrice 和 ItemPriceHistory 类之间有一对多的关系,我的映射如下:

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_Source。我只想删除当前的ItemPriceHistories 并更新以前的ItemPriceHistories 并添加新的ItemPriceHistory 条目。如何安全地更新 ItemPriceHistory 条目以及新的 ItemPriceHistory 条目?

谢谢!

【问题讨论】:

    标签: entity-framework one-to-many foreign-key-relationship


    【解决方案1】:

    我使用了一个应该适合您的 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;
    

    所以现在这些实体应该由 statemanager 更改和管理。 添加新条目....

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

    我不明白您为什么需要CLEAR 收藏 您是否更新现有记录并添加新记录? 祝你好运

    【讨论】:

      【解决方案2】:

      你不能只加载ItemPrice包括所有当前ItemPriceHistories,然后将这些历史记录的IsCurrent标志设置为false,并使用IsCurrent = 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();
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-09-13
        • 2018-11-13
        • 2021-01-07
        • 2018-11-24
        • 1970-01-01
        • 1970-01-01
        • 2017-04-14
        相关资源
        最近更新 更多