• EntityFramework 4.x 使用中遇到的问题 (1)


    在目前项目里,使用Code First的模式,但数据库已经存在,并且在数据库中并未设立外键关系,但在实体类中定义了实体关系。以上为这次遇到问题的背景。

    问题:

    在保存一组数据的时候,提示出现主键重复的问题。

    相关代码:

    Dictionary<<Tuple<string, int>, Detail> details = ... // 该数据有方法外部传入
    if(order.Details != null) // Order对象包含一个Detail对象的列表
    {
        foreach(var d in order.Details.ToArray())
        {
             var key = Tuple.Create(d.Id, d.No);
             if(details.ContainKey(key))
             {
                  // update the records with new value
                  details.Remove(key);
             }
             else
             {
                  dbContext.Entry(d).State = EntityState.Deleted;
             }
        }
        foreach(var d in details.Values)
        {
             dbContext.Details.Add(d);
        }
        dbContext.SaveChanges();
    }
    

      

    问题定位:

    首先根据异常,找出引起错误的数据,发现要保存的数据并不存在重复情况,同时在数据库里存在该数据,按理说不应出现这个错误。

    根据Log无法发现问题,只好调试程序了。当程序执行到var order = dbContext.Order.Find("id")的时候,发现数据库并不存在该id的数据,代码执行到这里,大概就已经发现了问题所在。由于数据里并不存在该id的数据,所以在前面Find的代码执行完毕后,根据输入的order数据创建了一个新的Order对象,这个时候,order的State是Added状态。当entry处于该状态时,在访问导航属性的时候,并不会尝试去数据库里读取Detail数据,所以执行上面的代码的时候,实际上是执行的dbContext.Details.Add(d)的部分。这也就造成了提示主键重复的异常。

    解决:

    既然是导航属性造成的问题,就只好选择绕开导航属性,直接通过Linq将Order数据读出来。

    Dictionary<<Tuple<string, int>, Detail> details = ... // 该数据有方法外部传入
    var detailsInDb = (from item in dbContext.Details where item.Id == order.Id select item).ToArray();
    if(detailsInDb != null)
    {
        foreach(var d in detailsInDb)
        {
             var key = Tuple.Create(d.Id, d.No);
             if(details.ContainKey(key))
             {
                  // update the records with new value
                  details.Remove(key);
             }
             else
             {
                  dbContext.Entry(d).State = EntityState.Deleted;
             }
        }
        foreach(var d in details.Values)
        {
             dbContext.Details.Add(d);
        }
        dbContext.SaveChanges();
    }
    

      

  • 相关阅读:
    Java中的Throwable类是不是受查异常?
    win10下写sh脚本出现^M字符的解决方法
    spring security中Authority、Role的区别
    idea调试框架时如何能够进入maven依赖包的源码
    推荐一个程序员阅读文章资料时的辅助神器
    MySQL添加、修改、撤销用户数据库操作权限的一些记录
    AndroidStudio布局编辑器强制刷新布局界面
    Android Stadio导入Android工程项目,只有Edit Configurations的解决办法
    GitHub克隆下载代码速度慢解决办法
    python各种类型日期转换大全
  • 原文地址:https://www.cnblogs.com/FMax/p/2455985.html
Copyright © 2020-2023  润新知