实体框架SaveChangesAsync不更新数据库
问题描述:
发票分类实体:实体框架SaveChangesAsync不更新数据库
public class InvoiceCategory
{
[Key]
Public int InvoiceCategoryID { get; set; }
[Required]
public string CategoryName { get; set; }
}
发票项目实体
public class InvoiceItem
{
[Key]
public int InvoiceItemID { get; set; }
[Required]
public int InvoiceID { get; set; }
[Required]
[Display(Name = "Date Completed")]
[DataType(DataType.Date)]
public DateTime? Date { get; set; }
[StringLength(50)]
public string InvoiceCategory { get; set; }
[Required]
[StringLength(200)]
public string Description { get; set; }
[Required]
[StringLength(20)]
public string Unit { get; set; }
[Required]
[DataType(DataType.Currency)]
[DisplayFormat(ApplyFormatInEditMode = false, DataFormatString = "{0:c}")]
public decimal Price { get; set; }
[Required]
[DefaultValue(1)]
public decimal? Quantity { get; set; }
public virtual Invoice Invoice { get; set; }
}
发票分类,编辑,查看
@model Accounts.Models.InvoiceCategory
<h2>Settings</h2>
<br />
<h4>Invoice Categories</h4>
<hr />
<form asp-action="Edit">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
@(Html.Kendo().Grid<Accounts.Models.InvoiceCategory>()
.Name("InvoiceCategory")
.ToolBar(tools =>
{
tools.Create().Text("New Category");
})
.Editable(editable => editable.Mode(GridEditMode.InCell).CreateAt(GridInsertRowPosition.Bottom).DisplayDeleteConfirmation(false))
.Columns(columns =>
{
columns.Bound(p => p.InvoiceCategoryID).Hidden().ClientTemplate("#= InvoiceCategoryID #" +
"<input type='hidden' name='[#= index(data)#].InvoiceCategoryID' value='#= InvoiceCategoryID #'/>"
);
columns.Bound(p => p.CategoryName).ClientTemplate("#= CategoryName #" +
"<input type='hidden' name='[#= index(data)#].CategoryName' value='#= CategoryName #'/>"
);
columns.Template("<a class='btn btn-danger btn-sm k-grid-delete'><span class='glyphicon glyphicon-trash'></span> </a>").Width(50);
})
.DataSource(dataSource => dataSource.Ajax()
.Model(model =>
{
model.Id(p => p.InvoiceCategoryID);
model.Field(p => p.InvoiceCategoryID).Editable(false);
})
.Read(read => read.Action("InvoiceCategories_Read", "Settings"))
.ServerOperation(false)
).Deferred()
)
<br />
<button type="submit" class="btn btn-success"><span class="glyphicon glyphicon-floppy-disk" style="vertical-align:middle;margin-top:-5px"></span> Save</button>
</form>
@section Scripts {
@Html.Kendo().DeferredScripts()
<script>
function index(dataItem) {
var data = $("#InvoiceCategory").data("kendoGrid").dataSource.data();
return data.indexOf(dataItem);
}
</script>
<style>
.k-grid {
width: 280px;
}
</style>
}
控制器发票类别更新方法:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(IEnumerable<InvoiceCategory> invoiceCategory)
{
if (ModelState.IsValid)
{
try
{
_context.InvoiceCategory.UpdateRange(invoiceCategory);
_context.SaveChangesAsync();
}
catch (Exception ex)
{
...
}
}
}
的值在视图中被改变和变化被发送到然而的更改不会颁布给数据库出于某种原因控制器的编辑方法用保存方法。
实体框架不支持像我这样没有整数标识列的查找表吗?还是我在做一些愚蠢的事情?
答
基本上你要做的是更新名为InvoiceCategory
的表的主键。无论如何,在你的代码的上下文中,如果你在数据库的背景下思考它,这是没有意义的。主键是记录的唯一标识符。你不应该能够更新它。
作为便笺,无论何时使用async
您都应至少使用一次使用await
。否则你的方法会同步执行。在你的情况下,缺少的await是这样的:
await _context.SaveChangesAsync();
更新
我认为你需要沿着以下的说法:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(IEnumerable<InvoiceCategory> invoiceCategories)
{
if (ModelState.IsValid)
{
try
{
foreach(var invoiceCategory in invoiceCategories)
{
if(invoiceCategory.InvoiceCategoryID == 0)
{
_context.InvoiceCategory.Add(invoiceCategory);
}
else
{
_context.InvoiceCategory.Update(invoiceCategory);
}
}
await _context.SaveChangesAsync();
}
catch (Exception ex)
{
...
}
}
}
+1感谢克里斯托。所以我明白我想要做什么是不可能的,我需要添加一个int标识列到查找表? – Reafidy
所以我已经添加了一个标识列到查找表(InvoiceCategoryID),仍然没有更新数据库。我不确定我是否正确使用updaterange。 – Reafidy
@Reafidy不用客气。你可以请你的数据库的架构图(只有表相关'InvoiceCategory')?此外,如果你能描述一个用例,这将会非常有帮助,以便理解你拥有什么以及你想实现什么。提前致谢 ! – Christos