Entity Framework SaveChanges() 错误?
Entity Framework SaveChanges() bug?
我有一个 CRUD 应用程序处理两个对象,卡片和日志。当用户创建、编辑或删除卡片时,会在数据库的 Log table 中创建一条新的 Log 记录。用户创建卡片时,Log记录的NewCard值为JSON数据,OldCard值为null。当用户删除卡片时,Log记录的OldCard值为JSON数据,NewCard为空。
但是,每当我删除一张卡片时,Entity Framework总是创建这条用红色圈起来的额外记录:
记录2101是IActionResult Create
中CreateNewLog(card, null)
之后的结果。记录2102和2103是IActionResult Delete
中CreateNewLog(null, oldCard)
之后的结果。记录 2103 是问题所在。如何停止创建此记录?
CardController.cs
private ICardData _cardData;
private ILogData _logData;
public CardController(ICardData cardData, ILogData logData)
{
_cardData = cardData;
_logData = logData;
}
// POST api/card
[HttpPost]
public IActionResult Create([FromBody] Card card)
{
try
{
if (ModelState.IsValid)
{
_cardData.Add(card);
CreateNewLog(card, null);
Response.StatusCode = (int)HttpStatusCode.Created;
return Json(new { Data = card });
}
}
catch (Exception ex)
{
Response.StatusCode = (int)HttpStatusCode.BadRequest;
return Json(new { Message = ex.Message });
}
return Json("Failed");
}
// DELETE api/card/1
[HttpDelete("{id}")]
public void Delete(int id)
{
Card oldCard = _cardData.Get(id).ShallowCopy();
CreateNewLog(null, oldCard);
_cardData.Delete(id);
}
public void CreateNewLog(Card newCard, Card oldCard)
{
Log newLog = new Log()
{
DateChanged = DateTime.Now,
CardId = newCard == null ? oldCard.CardId : newCard.CardId,
OldCard = JsonConvert.SerializeObject(oldCard),
NewCard = JsonConvert.SerializeObject(newCard),
User = "John Smith"
};
_logData.Add(newLog);
}
LogData.cs
public class SqlLogData : ILogData
{
private LitmusDbContext _context;
public SqlLogData(LitmusDbContext context)
{
_context = context;
}
public IEnumerable<Log> GetAll()
{
return _context.Logs.ToList();
}
public Log Get(int id)
{
return _context.Logs.FirstOrDefault(c => c.Id == id);
}
public void Add(Log newLog)
{
_context.Add(newLog);
_context.SaveChanges();
}
}
CardData.cs
public class SqlCardData : ICardData
{
private LitmusDbContext _context;
public SqlCardData(LitmusDbContext context)
{
_context = context;
}
public IEnumerable<Card> GetAll()
{
return _context.Cards.ToList();
}
public Card Get(int id)
{
Card card = _context.Cards.FirstOrDefault(c => c.Id == id);
return card;
}
public void Add(Card newCard)
{
_context.Add(newCard);
_context.SaveChanges();
}
public int Commit()
{
_context.SaveChanges();
return 0;
}
public void Update(Card newCard)
{
var oldCard = Get(newCard.Id);
if (oldCard != null)
{
oldCard.CardId = newCard.CardId;
oldCard.State = newCard.State;
_context.SaveChanges();
}
}
public void Delete(int id)
{
var cardToDelete = Get(id);
_context.Remove(cardToDelete);
_context.SaveChanges();
}
}
根据提供的代码,我看不出这是怎么可能的。在任何时候都不会将新卡和旧卡都提供给 CreateNewLog 函数,但有些东西正在将序列化的卡保存到 old/new 列。
能否在CreateNewLog函数中下断点,找出两个参数都提供的时间,然后查看调用堆栈?
我有一个 CRUD 应用程序处理两个对象,卡片和日志。当用户创建、编辑或删除卡片时,会在数据库的 Log table 中创建一条新的 Log 记录。用户创建卡片时,Log记录的NewCard值为JSON数据,OldCard值为null。当用户删除卡片时,Log记录的OldCard值为JSON数据,NewCard为空。
但是,每当我删除一张卡片时,Entity Framework总是创建这条用红色圈起来的额外记录:
记录2101是IActionResult Create
中CreateNewLog(card, null)
之后的结果。记录2102和2103是IActionResult Delete
中CreateNewLog(null, oldCard)
之后的结果。记录 2103 是问题所在。如何停止创建此记录?
CardController.cs
private ICardData _cardData;
private ILogData _logData;
public CardController(ICardData cardData, ILogData logData)
{
_cardData = cardData;
_logData = logData;
}
// POST api/card
[HttpPost]
public IActionResult Create([FromBody] Card card)
{
try
{
if (ModelState.IsValid)
{
_cardData.Add(card);
CreateNewLog(card, null);
Response.StatusCode = (int)HttpStatusCode.Created;
return Json(new { Data = card });
}
}
catch (Exception ex)
{
Response.StatusCode = (int)HttpStatusCode.BadRequest;
return Json(new { Message = ex.Message });
}
return Json("Failed");
}
// DELETE api/card/1
[HttpDelete("{id}")]
public void Delete(int id)
{
Card oldCard = _cardData.Get(id).ShallowCopy();
CreateNewLog(null, oldCard);
_cardData.Delete(id);
}
public void CreateNewLog(Card newCard, Card oldCard)
{
Log newLog = new Log()
{
DateChanged = DateTime.Now,
CardId = newCard == null ? oldCard.CardId : newCard.CardId,
OldCard = JsonConvert.SerializeObject(oldCard),
NewCard = JsonConvert.SerializeObject(newCard),
User = "John Smith"
};
_logData.Add(newLog);
}
LogData.cs
public class SqlLogData : ILogData
{
private LitmusDbContext _context;
public SqlLogData(LitmusDbContext context)
{
_context = context;
}
public IEnumerable<Log> GetAll()
{
return _context.Logs.ToList();
}
public Log Get(int id)
{
return _context.Logs.FirstOrDefault(c => c.Id == id);
}
public void Add(Log newLog)
{
_context.Add(newLog);
_context.SaveChanges();
}
}
CardData.cs
public class SqlCardData : ICardData
{
private LitmusDbContext _context;
public SqlCardData(LitmusDbContext context)
{
_context = context;
}
public IEnumerable<Card> GetAll()
{
return _context.Cards.ToList();
}
public Card Get(int id)
{
Card card = _context.Cards.FirstOrDefault(c => c.Id == id);
return card;
}
public void Add(Card newCard)
{
_context.Add(newCard);
_context.SaveChanges();
}
public int Commit()
{
_context.SaveChanges();
return 0;
}
public void Update(Card newCard)
{
var oldCard = Get(newCard.Id);
if (oldCard != null)
{
oldCard.CardId = newCard.CardId;
oldCard.State = newCard.State;
_context.SaveChanges();
}
}
public void Delete(int id)
{
var cardToDelete = Get(id);
_context.Remove(cardToDelete);
_context.SaveChanges();
}
}
根据提供的代码,我看不出这是怎么可能的。在任何时候都不会将新卡和旧卡都提供给 CreateNewLog 函数,但有些东西正在将序列化的卡保存到 old/new 列。
能否在CreateNewLog函数中下断点,找出两个参数都提供的时间,然后查看调用堆栈?