首页 新闻 会员 周边 捐助

关于EF的AddorUpdate

0
悬赏园豆:20 [已解决问题] 解决于 2020-06-18 09:59

我想用这个方法添加一个新实体,但是实体里面有些字段已经在数据库中村在。

比如:我想添加一个新Stydent,但是Student.School已经存在数据库里了,
我使用AddorUpdate(Student)的时候提示我School的主键冲突,也就是说Student的实体状态包括他的字段的实体只能都是Add或者modify,如果我这种情况怎么办呢?

        public bool AddOrUpdateOne(M model)
    {
        using (MyDBContext myDBContext = new MyDBContext())
        {
            var entity = ModelExtension<E, M>.GetEntity(model);

            myDBContext.Set<E>().AddOrUpdate(entity);

            var result = myDBContext.SaveChanges() > 0;
            return result;
        }
    }

我复现一下场景:

School school=new School();
Student student1=new Student();
Student student2=new Student();

student1.School=school;
student2.School=school;

AddOrUpdateOne(student1);

这里因为都是新元素,没有问题

AddOrUpdateOne(student2);

这里会报School的主键冲突

目前的解决办法只能是把Student和School放在同一个上下文去查,是不会抱错的

        public bool AddOrUpdateOne(Data data)
      {
        var entity = ModelExtension<DataEntity, Data>.GetNewEntity(data);
        using (MyDBContext myDBContext = new MyDBContext())
        {
            //myDBContext.DataEntity.Attach(entity);
            var sample = myDBContext.SampleEntity.Find(data.Sample.ID);
            if (sample != null)
            {
                entity.Sample = sample;
            }
            myDBContext.DataEntity.Add(entity);
            return myDBContext.SaveChanges() > 0;
        }
    }
问题补充:

查到了,addorupdate是暴力型的
https://www.michaelgmccarthy.com/2016/08/24/entity-framework-addorupdate-is-a-destructive-operation/

有莫得大哥知道该咋做啊

猝不及防的主页 猝不及防 | 老鸟四级 | 园豆:2878
提问于:2020-05-22 15:00
< >
分享
最佳答案
0

建议试试以下2个方法:

  • SaveChanges 移出 AddOrUpdateOne ,在 AddOrUpdateOne(student2) 之后一次进行 SaveChanges
  • 或者将 student2.School=school; 移至 AddOrUpdateOne(student1); 之后
收获园豆:20
dudu | 高人七级 |园豆:29568 | 2020-05-23 10:15

好的,我尝试一下

猝不及防 | 园豆:2878 (老鸟四级) | 2020-05-25 09:05

都不行,只要调用addorupdate就会把所有关联的实体变成add或者modify状态,目前我的冲突是 Student和School的实体状态不一致,与这个方法的一致性有冲突。

令我困惑的地方在于..我感觉换个写法就行了,现在想不出来这个写法是什么样的..

猝不及防 | 园豆:2878 (老鸟四级) | 2020-05-25 09:22

啊啊啊啊。发现个致命的问题

dudu大哥,我用automapper把ef的实体和数据模型分开...
实体类型中,student1和student2的school是一个实例,
一映射完,变成属性值相同的俩实例了..
您有没有这方面的经验是怎么处理这个的呢

猝不及防 | 园豆:2878 (老鸟四级) | 2020-05-25 10:47

@猝不及防: AutoMapper 映射出来的实例不在 EF 的跟踪范围

dudu | 园豆:29568 (高人七级) | 2020-05-25 11:29

@dudu: ...是的,我目前的写法都是手动更改entityState

猝不及防 | 园豆:2878 (老鸟四级) | 2020-05-25 11:40
其他回答(2)
0

看不懂你在说啥

会长 | 园豆:12463 (专家六级) | 2020-05-22 17:36

所长大哥,我修改了下问题,这下好理解了

支持(0) 反对(0) 猝不及防 | 园豆:2878 (老鸟四级) | 2020-05-22 17:42

啊啊啊啊。发现个致命的问题

会长大哥,我用automapper把ef的实体和数据模型分开...
实体类型中,student1和student2的school是一个实例,
一映射完,变成属性值相同的俩实例了..
您有没有这方面的经验是怎么处理这个的呢

支持(0) 反对(0) 猝不及防 | 园豆:2878 (老鸟四级) | 2020-05-25 10:48

@猝不及防: 没有

支持(0) 反对(0) 会长 | 园豆:12463 (专家六级) | 2020-05-25 11:27
0

很明显,你的school想插入两次,主键的值你肯定是在程序中给的,不是数据库自动生成。所以会报主键冲突,你把主2的主键值重新生成一下,再add就不会有这样的问题了

beggar_ | 园豆:10 (初学一级) | 2020-05-24 23:56

...我只想add一次,因为这就是同一个实体

支持(0) 反对(0) 猝不及防 | 园豆:2878 (老鸟四级) | 2020-05-25 09:05
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册