为避免先查询数据库,可以直接将 被修改的实体对象 添加到 EF中管理(此时为附加状态Attached),并手动设置其为未修改状态(Unchanged),同时设置被修改的实体对象 的 包装类对象 对应属性为修改状态。
优点:修改前不需要查询数据库。
1.创建修改的 实体对象
UserInfoes userInfonew = new UserInfoes()
{
UserId=userInfo.UserId,
Email = userInfo.Email,
FirstName = userInfo.FirstName,
LastName = userInfo.LastName,
LastUpdateBy = GetCurrentUserGuid(),
LastUpdate = DateTime.Now
};
2.添加到EF管理容器中,并获取 实体对象 的伪包装类对象
如果使用 Entry 附加 实体对象到数据容器中,则需要手动 设置 实体包装类的对象 的 状态为 Unchanged.
或者使用 Attach( Attach方法:将给定实体以 System.Data.EntityState.Unchanged 状态附加到上下文中从解释可以看出Attach方法主要目的就是把一个没有被dbContext跟踪的对象附加到dbCotext中使其被dbContext跟踪).
下面2句选择其一即可。
db.Entry(userInfonew).State = System.Data.Entity.EntityState.Unchanged;
或者
db.UserInfoes.Attach(userInfonew);
3.更新字段
①更新全部字段:
db.Entry(userInfonew).State = EntityState.Modified;
②更新部分字段:
db.Entry(userInfonew).Property(x => x.Email).IsModified = true;
4.更新到数据库
db.SaveChanges();
特别提醒:主键必须赋值,如果不赋值,会报错"Store update, insert, or delete statement affected an unexpected number of rows (0)…"
1. 查询实体后更新数据库
①.先查询要修改的原数据(注意此处不要加AsNoTracking(),加了无法更新)
var userInfoes= db.UserInfoes.Where(a => a.UserId== model.UserId).FirstOrDefault();
②.更新字段的值
userInfoes.LastUpdateBy = GetCurrentUserGuid();
userInfoes.LastUpdate = DateTime.Now;
③.更新到数据库
db.SaveChanges();
注意:EF查询出来的实体是无法更新主键的值。
否则会报如下错误:
2. 查询实体后不使用查询的实体,手动创建实体
var query = await (from a in db.MesMachineConfig
join c in db.Site_LinePosition
on new {A = a.LineNum,B = a.MCPosition} equals new {A= c.LineNum,B=c.MCPosition}
join b in db.DGHKROneReelNumManagerParamsSettings
on a.MachineNum equals b.MachineNum into rightRow
from rw in rightRow.DefaultIfEmpty()
where a.Enable == "Y" && a.Size == dghkrOneReelNumManagerParamsSettingsDto.Size
select new
{
a,
rw
}
/*这里不加AsNoTracking会报错"相同类型的其他实体已具有相同的主键值"
)/*.AsNoTracking()*/.ToListAsync();
query.ForEach(p =>
{
var mapResult = dghkrOneReelNumManagerParamsSettingsDto.MapTo<DGHKROneReelNumManagerParamsSettings>();
mapResult.MachineNum = p.a.MachineNum;
//添加
if (p.rw == null)
{
db.Add(mapResult);
}
//更新
else
{
db.Update(mapResult);
}
});
Attach的时候会报如下错误:因为相同类型的其他实体已具有相同的主键值。在使用 “Attach” 方法或者将实体的状态设置为 “Unchanged” 或 “Modified” 时如果图形中的任何实体具有冲突键值,则可能会发生上述行为。
解决办法: 查询的时候加AsNoTracking()