EF6更新记录导致参照完整性约束异常

时间:2016-02-01 20:54:22

标签: c# asp.net entity-framework

我有一个多对一关系的模型:

类库存

public class Stock
{
  [Key, Column(Order = 0)]
  [DatabaseGenerated(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity)]
  public int StockId { get; set; }

  [Key, Column(Order = 1)]
  [ForeignKey("Description")]
  public string Code { get; set; }

  public StockDescription Description { get; set; }

  [Required]
  [DisplayName("# Shares")]
  public int NumberOfShares { get; set; }

  public void UpdateStock(AddOperationViewModel viewModel)
  {
     this.NumberOfShares += viewModel.NumberOfShares;
     //Get some information from Yahoo!
     Controllers.DetailedInfosStocksController controller = new controllers.DetailedInfosStocksController();
     Models.DetailedQuoteQueryResultModel infos = controller.RetrieveStockDetailedInfos(this.Code);
     FillInfos(infos);
  }

  public void FillInfos(DetailedQuoteQueryResultModel infos)
  {
     if(Description == null)
     {
        Description = new StockDescription();
        Description.Code = infos.Symbol;
        Description.Name = infos.Name;
     }
     Description.FillInfos(infos);
  }
}

类库存描述

public class StockDescription
{ 
  [Key, Column(Order = 1)]
  public string Code { get; set; }

  [Required]
  public string Name { get; set; }

  [DisplayFormat(DataFormatString = "{0:F2}")]
  [DisplayName("Price")]
  public double LastPrice { get; set; }

  [DisplayFormat(DataFormatString = "{0:P2}")]
  [DisplayName("Variation")]
  public double ChangePercent { get; set; }

  public void FillInfos(DetailedQuoteQueryResultModel infos)
  {
     LastPrice = double.Parse(infos.LastTradePriceOnly);
     ChangePercent = double.Parse(infos.ChangeinPercent.Replace("%", "")) / 100;
  }
}

我正在尝试更新股票条目,如下所示:

  // POST: AddOperation
  [HttpPost]
  public ActionResult AddOperation(AddOperationViewModel viewModel)
  {
     if(ModelState.IsValid)
     {
        var existingStock = db.Stocks.Where(s => s.Code == viewModel.Code).FirstOrDefault<Stock>();

        if(existingStock == null)
        {
           Stock stock = new Stock(viewModel);
           db.Stocks.Add(stock);
        }
        else
        {
           existingStock.UpdateStock(viewModel);
           db.Entry(existingStock).State = EntityState.Modified;
        }
        db.SaveChanges();

        return PartialView("StockListPartialView", db.Stocks.Include("Description").ToList());
     }
  }

此例外:

  

发生了参照完整性约束违规:属性   定义引用约束的值不一致   在关系中的主要和依赖对象之间。

当我设置要修改的条目状态时,会出现

。到目前为止我找到的解决方法是设置existingStock.Description = null,但描述不再更新。

修改 两个类中的Code属性 enter image description here

1 个答案:

答案 0 :(得分:0)

如果您有现有Stock,则必须明确替换其StockDescription。为此,您需要对代码进行两处更改:

var existingStock = db.Stocks
                      .Include(s => s.StockDescription) // <= added
                      .Where(s => s.Code == viewModel.Code)
                      .FirstOrDefault<Stock>();

if(existingStock == null)
{
    Stock stock = new Stock(viewModel);
    db.Stocks.Add(stock);
}
else
{
    // Line added:
    db.Entry(existingStock.StockDescription).State = EntityState.Deleted;

    existingStock.UpdateStock(viewModel);
    // Not necessary:
    // db.Entry(existingStock).State = EntityState.Modified;
}
db.SaveChanges();

因此,您必须Include现有StockDescription。 (它不会被延迟加载加载,因为它不是virtual属性。)并且您已将其状态设置为已删除。现在EF知道它应该删除旧的描述并添加一个新描述。