C# 实体框架SaveChanges()错误?

C# 实体框架SaveChanges()错误?,c#,asp.net,entity-framework,entity-framework-6,entity-framework-core,C#,Asp.net,Entity Framework,Entity Framework 6,Entity Framework Core,我有一个CRUD应用程序处理两个对象,卡片和日志。当用户创建、编辑或删除卡时,将在数据库的日志表中创建新的日志记录。当用户创建卡时,日志记录的NewCard值为JSON数据,OldCard值为null。当用户删除一张卡时,日志记录的OldCard值为JSON数据,NewCard为空 但是,每当我删除一张卡时,Entity Framework总是创建这个用红色圈起来的额外记录: 记录2101是IActionResult Create中CreateNewLog(卡片,null)之后的结果。记录21

我有一个CRUD应用程序处理两个对象,卡片和日志。当用户创建、编辑或删除卡时,将在数据库的日志表中创建新的日志记录。当用户创建卡时,日志记录的NewCard值为JSON数据,OldCard值为null。当用户删除一张卡时,日志记录的OldCard值为JSON数据,NewCard为空

但是,每当我删除一张卡时,Entity Framework总是创建这个用红色圈起来的额外记录:

记录2101是
IActionResult Create
CreateNewLog(卡片,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);
    }
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();
        }
    }
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();
    }

}
公共类SqlLogData:ILogData { 私有LitmusDbContext\u上下文; 公共SqlLogData(LitmusDbContext上下文) { _上下文=上下文; } 公共IEnumerable GetAll() { 返回_context.Logs.ToList(); } 公共日志获取(int-id) { 返回_context.Logs.FirstOrDefault(c=>c.Id==Id); } 公共作废添加(日志新建日志) { _添加(newLog); _SaveChanges(); } } CardData.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);
    }
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();
        }
    }
公共类SqlCardData:ICardData
{
私有LitmusDbContext\u上下文;
公共SqlCardData(LitmusDbContext上下文)
{
_上下文=上下文;
}
公共IEnumerable GetAll()
{
return_context.Cards.ToList();
}
公共卡获取(int id)
{
Card Card=\u context.Cards.FirstOrDefault(c=>c.Id==Id);
回程卡;
}
公共作废添加(新卡)
{
_context.Add(newCard);
_SaveChanges();
}
公共int提交()
{
_SaveChanges();
返回0;
}
公共作废更新(新卡)
{
var oldCard=Get(newCard.Id);
如果(旧卡!=null)
{
oldCard.cardd=newCard.cardd;
oldCard.State=newCard.State;
_SaveChanges();
}
}
公共无效删除(int-id)
{
var cardToDelete=Get(id);
_删除(cardtodelet);
_SaveChanges();
}
}

根据提供的代码,我看不出这是怎么可能的。新卡和旧卡都没有提供给CreateNewLog函数,但有东西正在将序列化卡保存到旧/新列


你能在CreateNewLog函数中设置一个断点,找出何时提供了这两个参数,然后查看调用堆栈吗?

如果能看到_cardData.Delete(id)的代码,那就太好了;如果这一个出现了问题…您可以从web和sql profiler调试这些方法,以查看哪个方法调用了两次,或者调用的位置记录sql输出吗?它可能会让你知道为什么会发生这种情况。是否有SQL触发器在后台为您执行此操作?显示此对象的类的代码\u cardData。有什么原因吗?哎哟。你说得对。我刚刚意识到,每次执行删除操作时,我都会从前端代码中调用“Update”方法。