ef的Code First模式
现在有两个表,表A和表B...表A和表B是一对多的关系
class A{
......
public ICollection<B> B{set;get;}
......
}
class B{
......
public int AID{set;get;}
public A A{set;get;}
......
}
在mvc中分别有对应的DTO,利用Automapper将Dto转成实体A再保存时出现以下异常
Mapper.Map(DtoA,A);
Mapper.Map(DtoA.B,A.B);
Update(A);
---------------------------------
操作失败: 无法更改关系,因为一个或多个外键属性不可以为 null。对关系作出更改后,会将相关的外键属性设置为 null 值。如果外键不支持 null 值,则必须定义新的关系,必须向外键属性分配另一个非 null 值,或必须删除无关的对象。
-----------------------------------
检查了一下代码,并无调整或者删除关系的行为,外键值也是对的,所有的Hashcode和从数据库中获取出来的实体的Hashcode都是一样的,这代表和map出来的对象是同一个实体,可以表明此实体已存在于数据上下文之中
直接利用ef从数据库中获取数据再进行赋值修改操作是正常的...
于是按提示将AID改成可空的int?类型,然后再执行更新操作,现在是正常了,但观察数据库发现,它是将旧的记录的AID设为了NULL,然后再添加了一条新的记录?
还有一种情况也会出现这个问题,就是从数据库中获取到要修改的记录A之后,重新new一个List<B>给它,然后也会报相同的错误
请问有谁碰到过这种问题?
参照: http://visualstudiomagazine.com/blogs/tool-tracker/2013/11/updating--entities-with-automapper.aspx
custExisting = Mapper.Map(Of CustomerDTO, Customer)(custDTO, custExisting)
抱歉好像没这么用法吧?Of关键字是干嘛的?
@imegg:
人家那是 伪代码,给咱们示例用的。
你应该看下帖子,人家就是告诉咱们:
Mapper.Map<DtoA,A>(DtoA)的时候,先把A查询出来,然后Map的时候不要直接DtoA转换为A,
这样会把搞乱A和其他实体的关联关系,比如B,所以为了保证A的完整性,可以使用这样的方式进行Mapping。
伪代码:
//先把A从EF中查找出来
var entityA = db.AEntities.Find(AId);
//当你更新的时候要这样,保证A的完整性
Mapper.Map<DtoA,A>(DtoA,entityA);
@kaleyroy: 谢谢,目前我也是这个方案,将List中的实体分别再map一次
@imegg: 你好,想知道你具体的方法,我也遇到了同样的问题,谢谢。
@imegg: 请问list的改如何操作啊,比如说我以前的权限有3个,现在我改成了2个,新组装的集合也没有id啊
db.Entry(entity).State=EntityState.Added or EntityState.Modified