Сущность Framework SaveChanges () в другом DbContext вставляя ненужные строки - PullRequest
4 голосов
/ 24 мая 2011

моя модель супермаркета содержит класс StockItem и класс Alert, который содержит поле StockItem:

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; }
}

У меня есть функция, которая выбирает все StockItems одним DbContext:

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();
        }
     }
}

Проблема в том, что при сохранении оповещения в базу данных добавляется новый товар (с другим идентификатором), хотя он уже существует! какие-либо решения?

Ответы [ 2 ]

5 голосов
/ 24 мая 2011

Я думаю, вы должны 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();
        }
     }
}
0 голосов
/ 24 мая 2011
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 делает все стандартные элементы как независимые (отдельные элементы), и когда вы добавляете их в другой контекст, контекст предполагает, что это новый элемент, и он вставит его.

Лучшим способом будет сохранение контекста во всех изменениях, которые вы хотите внести. Также обратите внимание, что поддержание контекста в течение более длительного времени не означает, что вы будете постоянно поддерживать соединение с базой данных. EF автоматически открывает и закрывает соединение с базой данных, только когда вы выполняете запрос и вызываете изменения сохранения.

В противном случае вы должны присоединиться, как предложил Бен.

...