过去曾有过不同形式的问题,但我仍然无法让它发挥作用。
我正在使用dotnet core / ef核心构建一个站点,在一个页面上,我想使用jqGrid轻松编辑一个将经常更改的表。表称为CoList(公司列表)
我已经可以添加新行了,我可以删除它们,但是当我尝试编辑行时出现此错误:
实体类型'CoList'上的属性'AutoId'是键的一部分,因此无法修改或标记为已修改。
我首先创建了数据库,因为它在我开始使用这个新网站之前在其他地方使用过。
我的模型CoList.cs:
public partial class CoList
{
public int AutoId { get; set; }
public string CompanyName { get; set; }
public string CoLevel { get; set; }
public string CoCode { get; set; }
}
数据库上下文文件
modelBuilder.Entity<CoList>(entity =>
{
entity.HasKey(e => e.AutoId)
.HasName("PK_CoList");
entity.HasIndex(e => e.AutoId).IsUnique();
entity.Property(e => e.AutoId).HasColumnName("AutoID");
entity.Property(e => e.CoCode)
.IsRequired()
.HasColumnType("varchar(50)");
entity.Property(e => e.CoLevel)
.IsRequired()
.HasColumnType("varchar(50)");
entity.Property(e => e.CompanyName)
.IsRequired()
.HasColumnType("varchar(50)");
});
在编辑控制器中,我有:
public string EditCoList(int? Id, [Bind(include: "CompanyName, CoLevel, CoCode")] CoList coList)
{
FPSDemoContext db = _context;
string msg;
try
{
if (ModelState.IsValid)
{
db.Entry(coList).State = EntityState.Modified;
db.SaveChanges();
msg = "Saved";
}
else
{
msg = "Did not validate";
}
}
catch (DbUpdateConcurrencyException ex)
{
foreach (var entry in ex.Entries)
{
if (entry.Entity is CoList)
{
var databaseEntity = db.CoList.AsNoTracking().Single(p => p.AutoId == Id);
var databaseEntry = db.Entry(databaseEntity);
foreach (var property in entry.Metadata.GetProperties())
{
var proposedValue = entry.Property(property.Name).CurrentValue;
var originalValue = entry.Property(property.Name).OriginalValue;
var databaseValue = databaseEntry.Property(property.Name).CurrentValue;
entry.Property(property.Name).CurrentValue = proposedValue;
entry.Property(property.Name).OriginalValue = databaseEntry.Property(property.Name).CurrentValue;
}
}
else
{
msg = "Error occured:" + ex.Message;
throw new NotSupportedException("Concurrency conflict " + entry.Metadata.Name);
}
}
// Retry the save operation
db.SaveChanges();
msg = "Saved";
}
return msg;
}
点击“保存”后,代码会在“重试保存操作”中崩溃。
jqGrid代码:
$(function () {
$("#jqGrid").jqGrid({
regional: 'en',
url: "/SiteOptions/GetCoList",
datatype: 'json',
mtype: 'Get',
colNames: ['Id', 'Company Name', 'Company Level', 'Company Code'],
colModel: [
{ key: true, name: 'autoId', index: 'autoId', editable: false },
{ key: false, name: 'companyName', index: 'companyName', editable: true },
{ key: false, name: 'coLevel', index: 'coLevel', editable: true },
{ key: false, name: 'coCode', index: 'coCode', editable: true }],
pager: jQuery('#jqControls'),
rowNum: 10,
rowList: [10, 20, 30, 40, 50],
height: '100%',
viewrecords: true,
caption: 'Company List - Grid',
emptyrecords: 'No Companies to display',
jsonReader: {
root: "rows",
page: "page",
total: "total",
records: "records",
repeatitems: false,
Id: "0"
},
autowidth: true,
multiselect: false
}).navGrid('#jqControls', { edit: true, add: true, del: true, search: false, refresh: true },
{
zIndex: 100,
url: '/SiteOptions/EditCoList',
closeOnEscape: true,
closeAfterEdit: true,
recreateForm: true,
afterComplete: function (response) {
if (response.responseText) {
alert(response.responseText);
}
}
},
{
zIndex: 100,
url: "/SiteOptions/CreateCoList",
closeOnEscape: true,
closeAfterAdd: true,
afterComplete: function (response) {
if (response.responseText) {
alert(response.responseText);
}
}
},
{
zIndex: 100,
url: "/SiteOptions/DeleteCoList",
closeOnEscape: true,
closeAfterDelete: true,
recreateForm: true,
msg: "Are you sure you want to delete this row? ",
afterComplete: function (response) {
if (response.responseText) {
alert(response.responseText);
}
}
});
});
我已经阅读了这些答案,但他们没有帮助我,或者我误解了一些事情。
The property on entity type is part of a key and so cannot be modified or marked as modified
The property 'name' is part of the object's key information and cannot be modified. Entity Framework
https://github.com/aspnet/EntityFrameworkCore/issues/4560
编辑#2
根据评论,我已将编辑方法更改为:
public async Task<IActionResult> EditCoList(int Id, CoList coList)
{
string msg;
msg = "Model state is not valid";
if (Id != coList.AutoId)
{
msg = "Not Found";
}
if (ModelState.IsValid)
{
try
{
_context.Update(coList);
await _context.SaveChangesAsync();
msg = "Saved";
}
catch (DbUpdateConcurrencyException)
{
if (!CoListExists(coList.AutoId))
{
msg = "Concurrency Exception - Not Found";
}
else
{
msg = "Error";
throw;
}
}
}
return Content(msg);
}
private bool CoListExists(int? id)
{
return _context.CoList.Any(e => e.AutoId == id);
}
我也在使用viewmodel(我将在稍后的视图中使用额外的表):
namespace ASPNET_Core_1_0.Models.SiteOptionsViewModels
{
public class SiteOptionsViewModel
{
public IEnumerable<ASPNET_Core_1_0.Models.SiteOptions> SiteOptions { get; set; }
public IEnumerable<ASPNET_Core_1_0.Models.CoList> CoList { get; set; }
public ASPNET_Core_1_0.Models.SiteOptions AutoId { get; set; }
public ASPNET_Core_1_0.Models.SiteOptions CurrentMonth { get; set; }
public ASPNET_Core_1_0.Models.SiteOptions CurrentYear { get; set; }
public ASPNET_Core_1_0.Models.SiteOptions SelectedCompanyId { get; set; }
public ASPNET_Core_1_0.Models.CoList CompanyName { get; set; }
public ASPNET_Core_1_0.Models.CoList CoLevel { get; set; }
public ASPNET_Core_1_0.Models.CoList CoCode { get; set; }
}
}
在控制器中我像这样调用视图:
public async Task<IActionResult> Companylist()
{
ViewData["SubTitle"] = "Company List";
ViewData["Message"] = "Edit company list";
var model = new SiteOptionsViewModel
{
SiteOptions = await _context.SiteOptions.ToListAsync(),
CoList = await _context.CoList.ToListAsync()
};
return View(model);
}
我仍然遇到并发错误:
Microsoft.EntityFrameworkCore.DbContext:错误:保存更改时数据库中发生异常。 Microsoft.EntityFrameworkCore.DbUpdateConcurrencyException:数据库操作预计会影响1行但实际上影响了0行。自加载实体以来,数据可能已被修改或删除。有关理解和处理乐观并发异常的信息,请参阅http://go.microsoft.com/fwlink/?LinkId=527962。 at Microsoft.EntityFrameworkCore.Update.AffectedCountModificationCommandBatch.ThrowAggregateUpdateConcurrencyException(Int32 commandIndex,Int32 expectedRowsAffected,Int32 rowsAffected) 在Microsoft.EntityFrameworkCore.Update.AffectedCountModificationCommandBatch.d__6.MoveNext() ---从抛出异常的先前位置开始的堆栈跟踪结束---
有趣的是,当我从VS为我的数据库中的任何表生成CRUD控制器时,它始终有效,在编辑或保存编辑时完全没有问题。我按照生成的代码创建了自己的代码,但仍然得到了并发错误。
编辑#3
添加了prmNames的jqGrid js脚本:{id:“AutoId”}(根据Oleg评论),
$(function () {
$("#jqGrid").jqGrid({
regional: 'en',
prmNames: { id: "AutoId" },
url: "/SiteOptions/GetCoList",
datatype: 'json',
mtype: 'Get',
colNames: ['Id', 'Company Name', 'Company Level', 'Company Code'],
colModel: [
{ key: true, name: 'autoId', index: 'autoId', editable: false },
{ key: false, name: 'companyName', index: 'companyName', editable: true },
{ key: false, name: 'coLevel', index: 'coLevel', editable: true },
{ key: false, name: 'coCode', index: 'coCode', editable: true }],
pager: jQuery('#jqControls'),
rowNum: 10,
rowList: [10, 20, 30, 40, 50],
height: '100%',
viewrecords: true,
caption: 'Company List - Grid',
emptyrecords: 'No Companies to display',
jsonReader: {
root: "rows",
page: "page",
total: "total",
records: "records",
repeatitems: false,
Id: "0"
},
autowidth: true,
multiselect: false
}).navGrid('#jqControls', { edit: true, add: true, del: true, search: false, refresh: true },
{
zIndex: 100,
url: '/SiteOptions/EditCoList',
closeOnEscape: true,
closeAfterEdit: true,
recreateForm: true,
afterComplete: function (response) {
if (response.responseText) {
alert(response.responseText);
}
}
},
{
zIndex: 100,
url: "/SiteOptions/CreateCoList",
closeOnEscape: true,
closeAfterAdd: true,
afterComplete: function (response) {
if (response.responseText) {
alert(response.responseText);
}
}
},
{
zIndex: 100,
url: "/SiteOptions/DeleteCoList",
closeOnEscape: true,
closeAfterDelete: true,
recreateForm: true,
msg: "Are you sure you want to delete this row? ",
afterComplete: function (response) {
if (response.responseText) {
alert(response.responseText);
}
}
});
});
方法(根据Oleg评论):
public async Task<IActionResult> EditCoList(CoList coList)
{
string msg;
msg = "Model state is not valid";
/*if (Id != coList.AutoId)
{
msg = "Not Found";
}*/
if (ModelState.IsValid)
{
try
{
_context.Update(coList);
await _context.SaveChangesAsync();
msg = "Saved";
}
catch (DbUpdateConcurrencyException)
{
if (!CoListExists(coList.AutoId))
{
msg = "Concurrency Exception - Not Found";
}
else
{
msg = "Error";
throw;
}
}
}
return Content(msg);
}
仍然没有快乐
有人可以告诉我,我做错了什么吗?我还在学习,所以可能很简单。如果可能的话,你们中的任何人都可以向我们展示正确的解决方案吗?
答案 0 :(得分:1)
我建议您添加prmNames: { id: "autoId" }
选项,以便在将编辑结果发送到服务器时通知jqGrid使用autoId
属性而不是id
属性。
如果prmNames
由于某些原因(Guriddo jqGrid或代码中的错误)不起作用,但您看到具有正确值的id
属性被发送到服务器,那么您可以添加int id
EditCoList
参数coList.AutoId
id
以及_context.Update(coList);
之前基于object SingleKotlin {
// some members of SingleKotlin
@JvmStatic val x = 42
}
分配SingleKotlin.getX();
行 @Modifying(clearAutomatically = true)
@Query(value = "UPDATE stories s "
+ "SET rank = :reorderPosition"
+ " WHERE id = :selectedStory ;"
+ "UPDATE stories s "
+ "SET rank = rank+1"
+ " WHERE rank >= :reorderPosition "
+ "AND id <> :selectedStory ;"
+"SELECT id " +
"FROM stories s " +
"WHERE s.epic_Id = :epicId " +
"ORDER BY rank", nativeQuery = true)
List<Integer> reorder(@Param("selectedStory") int selectedStory, @Param("reorderPosition") int reorderPosition,@Param("epicId") int epicId);