4

我的超市模型包含一个 StockItem 类和一个包含 StockItem 字段的 Alert 类:

public class StockItem
{
    public int ID { get; set; }
    public string Name { get; set; }
    public int CurrentQuantity { get; set; }
    public int MinQuantity { get; set; }
}

public class Alert
{
    public int ID { get; set; }
    public int Message{ get; set; }
    public virtual StockItem StockItem { get; set; }
}

我有一个使用一个 DbContext 获取所有 StockItems 的函数:

using (var db = new MyDbContext())
{
     return db.StockItems.ToList();
}

还有另一个处理这些项目的函数,并在另一个 DbContext 中添加新的警报:

foreach (var item in items)
{
     if (item.CurrentQuantity < item.MinQuantity)
     {
        using (var db = new MyDbContext())
        {
            db.Alerts.Add(new Alert(){StockItem = item, Message = "Low Quantity"});
            db.SaveChanges();
        }
     }
}

问题是:当警报被保存时,一个新的库存项目(具有不同的 id)被添加到数据库中,尽管它已经存在了!任何解决方案?

4

2 回答 2

5

我想你应该Attach先存货。尝试这个:

foreach (var item in items)
{
     if (item.CurrentQuantity < item.MinQuantity)
     {
        using (var db = new MyDbContext())
        {
            db.StockItems.Attach(item);
            db.Alerts.Add(new Alert {StockItem = item, Message = "Low Quantity"});
            db.SaveChanges();
        }
     }
}
于 2011-05-24T08:16:42.357 回答
0
using (var db = new MyDbContext())
{
   var items = db.StockItems.ToList();
   foreach (var item in items)
   {
      if (item.CurrentQuantity < item.MinQuantity)
      {
         db.Alerts.Add(new Alert {StockItem = item, 
            Message = "Low Quantity"});
         db.SaveChanges();
      }
   }        
}

在这种情况下,您不需要附加。EF 只能跟踪其自身生命周期中的变化,在您这样做的第一种情况下,

using (var db = new MyDbContext())
{
     return db.StockItems.ToList();
}

您正在处理 MyDbContext,因此 EF 将所有库存项目作为独立的(分离的项目),当您将它们添加到不同的上下文时,上下文假定它是一个新项目,它将插入该项目。

最好的方法是在您想要进行的更改期间保持 Context 处于活动状态。另请注意,保持上下文活动更长时间并不意味着您将始终保持数据库连接打开。仅当您执行查询并调用保存更改时,EF 才会自动打开和关闭数据库连接。

否则,您必须按照 Ben 的建议附加。

于 2011-05-24T08:36:58.253 回答