C# 实体框架核心。如何正确更新相关数据?
这个问题很常见,但我仍然不明白如何正确更新相关实体 我有以下代码:C# 实体框架核心。如何正确更新相关数据?,c#,sql-update,entity-framework-core,one-to-many,C#,Sql Update,Entity Framework Core,One To Many,这个问题很常见,但我仍然不明白如何正确更新相关实体 我有以下代码: public async Task<bool> UpdateStepAssignedToLevelAsync(Step step, Guid levelId, int priority = -1) { var item = await this._context.StepLevels .Include(sl => sl.Step)
public async Task<bool> UpdateStepAssignedToLevelAsync(Step step, Guid levelId, int priority = -1)
{
var item = await this._context.StepLevels
.Include(sl => sl.Step)
.FirstOrDefaultAsync(x => x.StepId == step.Id && x.LevelId == levelId);
if (item == null)
{
return false;
}
//this._context.Entry(item).State = EntityState.Detached;
if (priority > -1)
{
item.Priority = priority;
}
item.Step = step;
//this._context.StepLevels.Update(item);
var rows = await this._context.SaveChangesAsync();
return rows > 0;
}
据我所知,自方法启动时的select请求以来,实体正在被跟踪。好的,但是当我分离实体并调用Update方法(参见注释行)时,Step实体没有被更改。但StepLevel确实如此:优先级正在改变。当我尝试调用just Update时,EF尝试插入新步骤,而不是更新现有步骤
那么,你能告诉我,这里最好的练习是什么
提前多谢 首先,分离实体不会分离相关实体,因此分离
项
不会分离项。步骤
通过检索。包括(sl=>sl.Step)
其次,由于您不想更改项.Step
,而是要更新现有的步骤
实体(x.StepId==Step.Id
),并且您知道上下文正在跟踪(包含)从数据库加载的相应步骤
实体,您应该使用通过条目(…).CurrentValues.SetValues
方法从分离的实体更新db实体的过程
所以移除
item.Step = step;
并改为使用以下选项:
this._context.Entry(item.Step).CurrentValues.SetValues(step);
最后一点。使用附着的实体时,不需要(不应该)使用
Update
方法。如果有任何实体被跟踪,更改跟踪器将自动检测更改的属性值。上下文正在跟踪从DB加载的相应步骤实体,因此会抛出此错误。您可以更新每个步骤属性-
public bool UpdateStepAssignedToLevelAsync(Step step, int levelId)
{
using(var context = new StackOverFlowDbContext())
{
var item = context.StepLevels
.Include(sl => sl.Step)
.FirstOrDefault(x => x.Id == step.Id && x.Id == levelId);
if (item == null)
{
return false;
}
// Updating Name property
item.Step.Name = step.Name;
// Other properties can be upadated
var rows = context.SaveChanges();
return rows > 0;
}
}
您想(1)更新
步骤
实体或(2)只更新步骤
导航属性的步骤
?虽然(2)在使用StepId==step.Id
检索StepLevel
时没有意义。我想同时更新step(一些字段,例如名称)和StepLevel(优先级)实体。这很有帮助!多谢各位!
public bool UpdateStepAssignedToLevelAsync(Step step, int levelId)
{
using(var context = new StackOverFlowDbContext())
{
var item = context.StepLevels
.Include(sl => sl.Step)
.FirstOrDefault(x => x.Id == step.Id && x.Id == levelId);
if (item == null)
{
return false;
}
// Updating Name property
item.Step.Name = step.Name;
// Other properties can be upadated
var rows = context.SaveChanges();
return rows > 0;
}
}