与Olivier MATROT讨论后,我意识到如何做到我所需的。
这个解决方案并不完美,因为它与提供程序绑定(SQL Server提供程序需要将byte[]作为并发标记属性),但是它可以按预期工作:
public class MyEntity
{
public int Id { get; set; }
public string Name { get; set; }
public uint ConcurrencyStamp { get; set; }
}
在这种情况下(如果使用迁移,需要从迁移代码中删除属性,以消除列创建尝试)
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<MyEntity>()
.Property(e => e.ConcurrencyStamp)
.ForNpgsqlHasColumnName("xmin")
.ForNpgsqlHasColumnType("xid")
.ValueGeneratedOnAddOrUpdate()
.IsConcurrencyToken();
}
编辑视图
@model Namespace.MyEntity
<form asp-action="Edit">
<div class="form-horizontal">
<h4>Person</h4>
<hr />
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<input type="hidden" asp-for="Id" />
<input type="hidden" asp-for="ConcurrencyStamp" />
<div class="form-group">
<label asp-for="Name" class="col-md-2 control-label"></label>
<div class="col-md-10">
<input asp-for="Name" class="form-control" />
<span asp-validation-for="Name" class="text-danger"></span>
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Save" class="btn btn-default" />
</div>
</div>
</div>
</form>
并默认的脚手架操作(仅为完成示例而设)
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(int id, [Bind("Id,Name,ConcurrencyStamp")] MyEntity model)
{
if (id != model.Id)
{
return NotFound();
}
if (ModelState.IsValid)
{
try
{
_context.Update(model);
await _context.SaveChangesAsync();
}
catch (DbUpdateConcurrencyException)
{
if (!MyEntityExists(model.Id))
{
return NotFound();
}
else
{
throw;
}
}
return RedirectToAction("Index");
}
return View(model);
}
因此,解决方案是将xmin值作为实体属性进行访问。