我尝试使用Entity Framework代码优先更新数据库中的单个值。
它引发了以下错误:
附加类型的实体 ' WarehouseAPI.Core.DataEntities.Models.TaskDetail'失败是因为 另一个相同类型的实体已经拥有相同的主键 值。使用'附加'方法或设置 一个实体的状态为“未变”'或者'修改'如果有任何实体 图表具有冲突的键值。这可能是因为某些实体 是新的,尚未收到数据库生成的键值。在 这种情况使用'添加'方法或“添加”#39;实体状态跟踪 图表然后将非新实体的状态设置为“未更改”。要么 '变形'酌情。
[Table("tblTaskDetail")]
public partial class tblTaskDetail
{
[Key]
public int TaskDetailID { get; set; }
public int? ScheduleId { get; set; }
[Required]
[StringLength(50)]
public string RobotID { get; set; }
public Guid? SessionID { get; set; }
[Required]
[StringLength(50)]
public string TaskStatus { get; set; }
[Column(TypeName = "datetime2")]
public DateTime? TaskScheduledOn { get; set; }
[StringLength(250)]
public string TaskSummary { get; set; }
[Column(TypeName = "datetime2")]
public DateTime? TaskStartedOnUtc { get; set; }
[Column(TypeName = "datetime2")]
public DateTime? TaskCompletedOnUtc { get; set; }
}
public class TaskDetail
{
public int TaskDetailID { get; set; }
public int? ScheduleId { get; set; }
public string RobotID { get; set; }
public Guid? SessionID { get; set; }
public string TaskStatus { get; set; }
public DateTime TaskScheduledOn { get; set; }
public string TaskSummary { get; set; }
public DateTime TaskStartedOnUtc { get; set; }
public DateTime TaskCompletedOnUtc { get; set; }
}
public class TaskDetailMapper:EntityTypeConfiguration<TaskDetail>
{
public TaskDetailMapper()
{
this.ToTable("tblTaskDetail");
this.HasKey(hk => hk.TaskDetailID);
this.Property(o => o.RobotID).HasColumnName("RobotID");
this.Property(o => o.ScheduleId).HasColumnName("ScheduleId");
this.Property(o => o.SessionID).HasColumnName("SessionID");
this.Property(o => o.TaskCompletedOnUtc).HasColumnName("TaskCompletedOnUtc");
this.Property(o => o.TaskDetailID).HasColumnName("TaskDetailID");
this.Property(o => o.TaskScheduledOn).HasColumnName("TaskScheduledOn");
this.Property(o => o.TaskStartedOnUtc).HasColumnName("TaskStartedOnUtc");
this.Property(o => o.TaskStatus).HasColumnName("TaskStatus");
this.Property(o => o.TaskSummary).HasColumnName("TaskSummary");
}
}
public partial class WarehouseAPIContext : DbContext
{
public WarehouseAPIContext() : base("name=WarehouseAPIContext")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new TaskDetailMapper());
}
}
public class TaskDetailRepository:APIRepository<TaskDetail>
{
WarehouseAPIContext _context;
public TaskDetailRepository(WarehouseAPIContext context):base(context)
{
_context = context;
}
public TaskDetail UpdateTaskStartingTime(TaskDetail entity)
{
try
{
var taskDetail = new TaskDetail() { TaskStartedOnUtc = entity.TaskStartedOnUtc, TaskStatus = entity.TaskStatus,SessionID = entity.SessionID, TaskDetailID = entity.TaskDetailID };
dbSet.Attach(taskDetail); // THROWS THE ERROR
_context.Entry(taskDetail).Property(x => x.TaskStartedOnUtc).IsModified = true;
_context.SaveChanges();
return entity;
}
catch (Exception ex)
{
throw ex;
}
}
}
public class APIRepository<T> where T:class
{
internal WarehouseAPIContext wContext;
internal DbSet<T> dbSet;
public APIRepository(WarehouseAPIContext context)
{
wContext = context;
dbSet = context.Set<T>();
}
public virtual T Update(T entity)
{
try
{
var entry = wContext.Entry(entity);
dbSet.Attach(entity);
entry.State = EntityState.Modified;
wContext.SaveChanges();
return entity;
}
catch (Exception ex)
{
//ExceptionHandler.Handle(ex);
return null;
}
}
}
答案 0 :(得分:1)
有两种方法可以执行此操作,首先加载要更新的实体,将更改复制到此实体并保存更改,我更喜欢,第二个选项是加载要更新的实体,然后de attach它,并将其附加回来,最后保存上下文更改。
您无法附加已经附加的实体,EF会再次插入该对象