I receive the error mentioned in the title:
Cannot insert explicit value for identity column in table ‘Products Discussed’ when IDENTITY_INSERT is set to OFF.
I have checked out multiple forum posts, and scoured the internet, and I still cannot fix the issue.
A contact report will be submitted to the database, and a product discussed table will also be updated. The contact report worked perfectly, but the error occurred with the product discussed table.
Please see all the code below:
ContactReportController.cs
[HttpGet]
public async Task<IActionResult> Submit()
{
var contactReport = new ContactReport
{
ProductsDiscussed = new List<ProductDiscussed>
{
new ProductDiscussed() // Add one default item
},
Report_Date = DateTime.Now
};
// Load necessary data for the form
await LoadFormDataAsync();
return View(contactReport);
}
[HttpPost]
public async Task<IActionResult> Submit(ContactReport contactReport)
{
if (User?.Identity?.IsAuthenticated == true)
{
if (ModelState.IsValid)
{
try
{
_logger.LogInformation("Model is valid. Adding contact report to context.");
// Add the ContactReport to the context
_context.ContactReports.Add(contactReport);
await _context.SaveChangesAsync();
// Ensure EF Core recognizes each product as a new entity
foreach (var product in contactReport.ProductsDiscussed)
{
// Set the foreign key
product.ReportID = contactReport.Report_Id;
// Mark the product as a new entity
_context.ProductsDiscussed.Add(product);
}
await _context.SaveChangesAsync();
return RedirectToAction("Index");
}
catch (Exception ex)
{
_logger.LogError(ex, "An error occurred while saving the contact report.");
ModelState.AddModelError("", "An error occurred while saving the report. Please try again.");
}
}
else
{
_logger.LogWarning("Model state is invalid.");
foreach (var error in ModelState.Values.SelectMany(v => v.Errors))
{
_logger.LogWarning(error.ErrorMessage);
}
}
}
else
{
_logger.LogWarning("User is not authenticated.");
return Unauthorized();
}
// Reload data if ModelState is invalid
await LoadFormDataAsync(); // Method to load the data needed for the form
return View(contactReport);
}
private async Task LoadFormDataAsync()
{
var staffList = await _context.Staff.OrderBy(s => s.Name).ToListAsync();
ViewBag.StaffList = new SelectList(staffList, "StaffId", "Name");
var countries = await _context.Countries.OrderBy(c => c.CountryName).ToListAsync();
ViewBag.Countries = new SelectList(countries, "CountryCode", "CountryName");
var productCategories = await _context.ProductCategories.OrderBy(c => c.CategoryName).ToListAsync();
ViewBag.ProductCategories = new SelectList(productCategories, "CategoryID", "CategoryName");
var customers = await _context.Customers.ToListAsync();
var customerList = customers
.Select(c => new
{
c.CustomerId,
DisplayName = string.IsNullOrEmpty(c.City)
? $"{c.Name} {c.Surname} - {c.Country}"
: $"{c.Name} {c.Surname} - {c.Country}, {c.City}",
SortKey = string.IsNullOrEmpty(c.Name) ? c.Surname : $"{c.Name} {c.Surname}"
})
.OrderBy(c => c.SortKey)
.ToList();
ViewBag.CustomerList = new SelectList(customerList, "CustomerId", "DisplayName");
}
Submit.cshtml
<div id="productsContainer">
@for (int i = 0; i < Model.ProductsDiscussed.Count; i++)
{
<div class="card mb-3">
<div class="card-body">
<div class="form-group">
<label asp-for="ProductsDiscussed[i].BrandProductCategoriesID">Product Category</label>
<select asp-for="ProductsDiscussed[i].BrandProductCategoriesID" class="form-control" asp-items="ViewBag.ProductCategories">
<option value="">Select a product category</option>
</select>
<span asp-validation-for="ProductsDiscussed[i].BrandProductCategoriesID" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="ProductsDiscussed[i].Sample">Sample Used</label>
<select asp-for="ProductsDiscussed[i].Sample" class="form-control">
<option value="false">No</option>
<option value="true">Yes</option>
</select>
<span asp-validation-for="ProductsDiscussed[i].Sample" class="text-danger"></span>
</div>
</div>
</div>
}
</div>
<button type="button" id="addProductButton" class="btn btn-secondary mt-3">Add Another Product</button>
Products Discussed ID
IDENTITY(1,1) is used
[Products Discussed ID] [int] IDENTITY(1,1) NOT NULL,
ContactReport.cs
public ContactReport()
{
ProductsDiscussed = new List<ProductDiscussed>();
}
// Text in-between
[NotMapped]
public List<ProductDiscussed> ProductsDiscussed { get; set; } = new List<ProductDiscussed>();
Product Discussed.cs
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Column("Products Discussed ID")]
public int ProductsDiscussedID { get; set; } // Manually managed ID
Error received after submitting report
CustomerDatabase.Controllers.ContactReportController: Information: Model is valid. Adding contact report to context.
Microsoft.EntityFrameworkCore.Database.Command: Information: Executed DbCommand [Parameters=[@p0='SUR238' (Nullable = false) (Size = 4000), @p1='test' (Nullable = false) (Size = 4000), @p2='test' (Nullable = false) (Size = 4000), @p3='' (Nullable = false) (Size = 4000), @p4='test' (Nullable = false) (Size = 4000), @p5='2024-08-12T00:00:00.0000000', @p6='test' (Nullable = false) (Size = 4000), @p7='STA11' (Nullable = false) (Size = 4000)], CommandType='Text', CommandTimeout='30']
SET IMPLICIT_TRANSACTIONS OFF;
SET NOCOUNT ON;
INSERT INTO [Contact Report] ([Customer ID], [Feedback], [Follow Up], [Location], [Notes], [Report Date], [Report Description], [Staff Id])
OUTPUT INSERTED.[Id]
VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7);
Microsoft.EntityFrameworkCore.Database.Command: Information: Executed DbCommand [Parameters=[@p8='3', @p9='195', @p10='False'], CommandType='Text', CommandTimeout='30']
SET IMPLICIT_TRANSACTIONS OFF;
SET NOCOUNT ON;
INSERT INTO [Products Discussed] ([Brand Product Categories], [Report ID], [Sample])
OUTPUT INSERTED.[Products Discussed ID]
VALUES (@p8, @p9, @p10);
Exception thrown: 'Microsoft.Data.SqlClient.SqlException' in Microsoft.Data.SqlClient.dll
Microsoft.EntityFrameworkCore.Database.Command: Error: Failed executing DbCommand [Parameters=[@p0='18', @p1='3', @p2='195', @p3='False'], CommandType='Text', CommandTimeout='30']
SET IMPLICIT_TRANSACTIONS OFF;
SET NOCOUNT ON;
INSERT INTO [Products Discussed] ([Products Discussed ID], [Brand Product Categories], [Report ID], [Sample])
VALUES (@p0, @p1, @p2, @p3);
Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while saving the entity changes. See the inner exception for details.
---> Microsoft.Data.SqlClient.SqlException (0x80131904): Cannot insert explicit value for identity column in table 'Products Discussed' when IDENTITY_INSERT is set to OFF.