防止更新 EF-core 中的导航属性
Prevent updates to navigation properties in EF-core
请问我们如何防止EF.core在我们创建新的主实体时尝试insert/update外键表?
抛出异常:
SqlException: Cannot insert explicit value for identity column in table 'clients' when IDENTITY_INSERT is set to OFF.
Cannot insert explicit value for identity column in table 'guards' when IDENTITY_INSERT is set to OFF.
Cannot insert explicit value for identity column in table 'penalties' when IDENTITY_INSERT is set to OFF.
我的代码如下:
public class Offence
{
[Key]
public Int32 offence_id { get; set; }
public Int32? guard_id { get; set; }
public Int32? penalty_id { get; set; }
public DateTime? dt_recorded { get; set; }
public Int32? salary_id { get; set; }
public Decimal? amount { get; set; }
public String status { get; set; }
public Int32? site_id { get; set; }
public Guard Guard { get; set; }
public Salary Salary { get; set; }
public Site Site { get; set; }
public Penalty Penalty { get; set; }
}
任何创建新 Offence
的尝试都会出错,因为 EF.core 试图 运行 插入相关导航属性:
public Guard Guard { get; set; }
public Salary Salary { get; set; }
public Site Site { get; set; }
public Penalty Penalty { get; set; }
我们如何防止这种情况发生?
编辑:创建和更新代码
[HttpPost]
public async Task<IActionResult> Create([FromBody] Offence o)
{
if (o == null)
{
return BadRequest();
}
o.last_modified_by = int.Parse(((ClaimsIdentity)User.Identity).Claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier)?.Value);
o.last_modified = DateTime.Now;
await db.AddAsync(o);
await db.SaveChangesAsync();
return CreatedAtRoute("GetOffenceAsync", new { id = o.offence_id }, o);
}
您需要将这些属性设置为 virtual
。这样 EF 就知道什么是模型的一部分以及什么是导航 属性。此外,这将启用您需要的 LazyLoading 机制。
public virtual Guard Guard { get; set; }
public virtual Salary Salary { get; set; }
public virtual Site Site { get; set; }
public virtual Penalty Penalty { get; set; }
您的导航属性似乎有值,请在保存之前检查您的导航属性是否有空引用; EF Core 保存逻辑尝试保存具有价值的导航属性。
如果有用请告诉我
为了让它工作,我必须在保存之前 null-out
导航属性。
但是,如果使用 CreatedAtRoute
发送初始对象,则需要缓存 nulled-out
属性并将它们添加回 return:
之前
实际代码:
[HttpPost]
public async Task<IActionResult> Create([FromBody] Offence o)
{
if (o == null)
{
return BadRequest();
}
o.last_modified_by = int.Parse(((ClaimsIdentity)User.Identity).Claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier)?.Value);
o.last_modified = DateTime.Now;
var _g = o.Guard;
var _p = o.Penalty;
var _s = o.Site;
o.Guard = null;
o.Penalty = null;
o.Site = null;
await db.AddAsync(o);
await db.SaveChangesAsync();
o.Guard = _g;
o.Penalty = _p;
o.Site = _s;
return CreatedAtRoute("GetOffenceAsync", new { id = o.offence_id }, o);
}
请问我们如何防止EF.core在我们创建新的主实体时尝试insert/update外键表?
抛出异常:
SqlException: Cannot insert explicit value for identity column in table 'clients' when IDENTITY_INSERT is set to OFF.
Cannot insert explicit value for identity column in table 'guards' when IDENTITY_INSERT is set to OFF.
Cannot insert explicit value for identity column in table 'penalties' when IDENTITY_INSERT is set to OFF.
我的代码如下:
public class Offence
{
[Key]
public Int32 offence_id { get; set; }
public Int32? guard_id { get; set; }
public Int32? penalty_id { get; set; }
public DateTime? dt_recorded { get; set; }
public Int32? salary_id { get; set; }
public Decimal? amount { get; set; }
public String status { get; set; }
public Int32? site_id { get; set; }
public Guard Guard { get; set; }
public Salary Salary { get; set; }
public Site Site { get; set; }
public Penalty Penalty { get; set; }
}
任何创建新 Offence
的尝试都会出错,因为 EF.core 试图 运行 插入相关导航属性:
public Guard Guard { get; set; }
public Salary Salary { get; set; }
public Site Site { get; set; }
public Penalty Penalty { get; set; }
我们如何防止这种情况发生?
编辑:创建和更新代码
[HttpPost]
public async Task<IActionResult> Create([FromBody] Offence o)
{
if (o == null)
{
return BadRequest();
}
o.last_modified_by = int.Parse(((ClaimsIdentity)User.Identity).Claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier)?.Value);
o.last_modified = DateTime.Now;
await db.AddAsync(o);
await db.SaveChangesAsync();
return CreatedAtRoute("GetOffenceAsync", new { id = o.offence_id }, o);
}
您需要将这些属性设置为 virtual
。这样 EF 就知道什么是模型的一部分以及什么是导航 属性。此外,这将启用您需要的 LazyLoading 机制。
public virtual Guard Guard { get; set; }
public virtual Salary Salary { get; set; }
public virtual Site Site { get; set; }
public virtual Penalty Penalty { get; set; }
您的导航属性似乎有值,请在保存之前检查您的导航属性是否有空引用; EF Core 保存逻辑尝试保存具有价值的导航属性。
如果有用请告诉我
为了让它工作,我必须在保存之前 null-out
导航属性。
但是,如果使用 CreatedAtRoute
发送初始对象,则需要缓存 nulled-out
属性并将它们添加回 return:
实际代码:
[HttpPost]
public async Task<IActionResult> Create([FromBody] Offence o)
{
if (o == null)
{
return BadRequest();
}
o.last_modified_by = int.Parse(((ClaimsIdentity)User.Identity).Claims.FirstOrDefault(c => c.Type == ClaimTypes.NameIdentifier)?.Value);
o.last_modified = DateTime.Now;
var _g = o.Guard;
var _p = o.Penalty;
var _s = o.Site;
o.Guard = null;
o.Penalty = null;
o.Site = null;
await db.AddAsync(o);
await db.SaveChangesAsync();
o.Guard = _g;
o.Penalty = _p;
o.Site = _s;
return CreatedAtRoute("GetOffenceAsync", new { id = o.offence_id }, o);
}