【发布时间】:2017-01-29 23:36:22
【问题描述】:
我正在尝试使用实体框架代码优先更新数据库中的单个值。
它抛出以下错误:
附加类型的实体 'WarehouseAPI.Core.DataEntities.Models.TaskDetail' 失败,因为 另一个相同类型的实体已经具有相同的主键 价值。使用“附加”方法或设置 如果实体中有任何实体,则实体的状态为“未更改”或“已修改” 图有冲突的键值。这可能是因为某些实体 是新的,尚未收到数据库生成的键值。在 这种情况下使用 'Add' 方法或 'Added' 实体状态来跟踪 图表,然后将非新实体的状态设置为“未更改”或 酌情“修改”。
[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;
}
}
}
【问题讨论】:
-
该实体是否已在上下文缓存中可用?您是否在同一上下文中的其他位置从数据库中加载该实体?还有为什么有两个上下文对象 -
dbSet和_context。我认为,当您使用.Entry时,您可以跳过.Attach部分
标签: c# asp.net entity-framework