【发布时间】:2019-10-28 15:51:10
【问题描述】:
我有如下设置。
-
Supermaster拥有Master的集合。 -
Master具有对ReferencePK Id 的 FK 引用 -
Reference表具有只读引用数据。
在 ef 代码中,当我从 Supermaster 表加载记录时,我根据某些条件将 reference 添加到每个 Master。
在提交Supermaster 时,我希望Supermaster 与所有Master 参考Reference 一起保存。
但在dbContext.SaveChanges() 上,EF 尝试将记录插入Reference,但由于 PK 约束而失败。
我到目前为止所尝试的
我尝试使用 Fluent API 与外键创建一对一关系。
我在保存上下文之前尝试过分离实体
_context.Entry(programmingRecord.ProgrammingRecordParameters.Select(x=>x.ValidationRule)).State = EntityState.Detached;
.
这是代码。
实体
Public class Supermaster
{
public virtual ICollection<Master> ProgrammingRecordParameters { get; set; }
}
public class Reference
{
public int Id { get; set; }
public string Description { get; set; }
}
public class Master
{
public int Id { get; set; }
public string DataGroup { get; set; }
[ForeignKey("ValidationRuleId")]
public Reference ValidationRule { get; set; }
public int? ValidationRuleId { get; set; }
}
API
private void AddParameter(
Supermaster rec,
Master programmableParameter)
{
var param = new Master
{
DataGroup = programmableParameter.DataGroup,
ValidationRule = _context.References.FirstOrDefault(x=>x.Description==programmableParameter.DataGroup
};
rec.ProgrammingRecordParameters.Add(param);
}
public IActionResult PostProgrammingRecord([FromBody] Master programmingRecord)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var repo = new ProgrammingRepository(_context);
_context.ProgrammingRecords.Add(programmingRecord);
_context.SaveChanges();
}
下面是错误堆栈
HResult=0x80131500
Message=An error occurred while updating the entries. See the inner exception for details.
Source=Microsoft.EntityFrameworkCore.Relational
StackTrace:
at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.Execute(IRelationalConnection connection)
at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.Execute(DbContext _, ValueTuple`2 parameters)
at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.Execute[TState,TResult](TState state, Func`3 operation, Func`3 verifySucceeded)
at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.Execute(IEnumerable`1 commandBatches, IRelationalConnection connection)
at Microsoft.EntityFrameworkCore.Storage.RelationalDatabase.SaveChanges(IReadOnlyList`1 entries)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(IReadOnlyList`1 entriesToSave)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(Boolean acceptAllChangesOnSuccess)
at Microsoft.EntityFrameworkCore.DbContext.SaveChanges(Boolean acceptAllChangesOnSuccess)
at Microsoft.EntityFrameworkCore.DbContext.SaveChanges()
at RadioTMS.Web.Controllers.API.ProgrammingController.PostProgrammingRecord(ProgrammingRecord programmingRecord) in D:\TMS_Git_Repo\radio-tms\RadioTMS.Web\Controllers\API\ProgrammingController.cs:line 181
at Microsoft.Extensions.Internal.ObjectMethodExecutor.Execute(Object target, Object[] parameters)
at Microsoft.AspNetCore.Mvc.Internal.ActionMethodExecutor.SyncActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeActionMethodAsync>d__12.MoveNext()
Inner Exception 1:
SqlException: Cannot insert explicit value for identity column in table 'ValidationRules' when IDENTITY_INSERT is set to OFF.
【问题讨论】:
-
context.Entry(param.ValidationRule).State在rec.ProgrammingRecordParameters.Add(param);之前和之后返回什么? -
@Minijack - 相当于
Unchanged -
@SKDesai 您的
AddParameter(programmableParameter)方法会在内部创建一个新的param,并且不会更改原始programmableParameter。因此,当您稍后调用_context.ProgrammingRecords.Add(programmingRecord);时,您将在programmingRecord而不是param上进行操作。因为programmingRecord.ValidationRule没有被跟踪,EF-Core会尝试插入/更新数据库,导致异常。 -
@itminus - 啊……我认为是这样。我认为在这种情况下,我需要明确告诉 EF 在保存 DBContext 之前不要更新验证规则。让我试一试,我会更新...
标签: c# asp.net-core ef-code-first entity-framework-core ef-core-2.1