Reputation: 8481
Invoice Category Entity:
public class InvoiceCategory
{
[Key]
Public int InvoiceCategoryID { get; set; }
[Required]
public string CategoryName { get; set; }
}
Invoice Item Entity
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; }
}
Invoice Category Edit View
@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>
}
Controller Invoice Category Update Method:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(IEnumerable<InvoiceCategory> invoiceCategory)
{
if (ModelState.IsValid)
{
try
{
_context.InvoiceCategory.UpdateRange(invoiceCategory);
_context.SaveChangesAsync();
}
catch (Exception ex)
{
...
}
}
}
The values are being changed in the view and the changes are being sent to the Edit method of the controller however the changes are not promulgated to the database for some reason with the save method.
Can Entity framework not support a lookup table with no integer identity column like I have? Or am I doing something stupid?
Upvotes: 2
Views: 7247
Reputation: 53958
Essentially that you are trying to do is to update the Primary Key of the table called InvoiceCategory
. Irrespectively, with the context of your code, if you think about it in the context of databses, this does not make sense. A Primary Key is the unique identifier of a record. You shouldn't be able to update it.
As a side note, whenever you use async
you should use at least one use await
. Otherwise your method would be executed synchronously. In your case the missing await is this:
await _context.SaveChangesAsync();
Update
I think that you need is something along the following lines:
[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)
{
...
}
}
}
Upvotes: 4