I have a Razor Pages app that I am design and then publishing.
When I run it on Server 2016 in IIS, I can add items to the database and update items in the database, but when I try to remove an item from the database, it gives me a 500 error. I thought it was an issue with the specific code where I try to remove a record from the DB, but it does the same thing in other places.
On my computer, it works as it should.
Here is one of the examples:
public async Task<IActionResult> OnPostDeleteOrderLine(string subPO)
{
string PON = "";
if(subPO != null)
{
SteelOrderLine orderLine =
_MCSContext
.SteelOrderLines
.First(sol => sol.SubPO.Equals(subPO));
PON = _MCSContext
.SteelOrders
.First(so => so.ID == orderLine.SteelOrdersID)
.PONumber;
_MCSContext.SteelOrderLines.Remove(orderLine);
await _MCSContext.SaveChangesAsync();
}
return RedirectToPage("CRUD", "EditLine", new { PONumber = PON });
}
Are there any settings in sql or in my Razor Pages project that might affect only Remove in the published project?
CodePudding user response:
Thanks for the help on this one. Based on Igor's comment, I enabled Development Mode on the published razor page. The error turned out to be:
The DELETE permission was denied on the object 'SteelOrderLines', database 'MCS', schema 'dbo'
When I set up the database in MS SQL, I enabled the 'INSERT' permissions, but in order to use the REMOVE entity framework command, I had to enable 'DELETE' as well.
CodePudding user response:
Also worth noting from your example:
SteelOrderLine orderLine =
_MCSContext
.SteelOrderLines
.First(sol => sol.SubPO.Equals(subPO));
if you expect one item back, use Single
rather than First
. First implies that if there are more than one match take the first one. This can conceal potential data issues / code assumptions, and cases where you legitimately expect more than one as a possibility you should always have an OrderBy
(Descending) clause to ensure the selection is predictable & repeatable.
PON = _MCSContext
.SteelOrders
.First(so => so.ID == orderLine.SteelOrdersID)
.PONumber;
For this line, you can bump performance by using:
PON = _MCSContext
.SteelOrders
.Where(so => so.ID == orderLine.SteelOrdersID)
.Select(so => so.PONumber)
.Single();
In your example you are loading the entire Steel Order entity just to get the PONumber. In the second example the SQL generated and executed will just return the PONumber. This can result in better performance (less memory use/processing to materialize tracked entities) If that column is indexed it can be a magnitudes faster query.