Hi,
Actually, the project doesn't work, and especially if I let class RazorPagesMovie.Models.Movie as follow:
public int ID { get; set; }
But this work if we replace by
public int Id { get; set; }
I'm on Linux and I've tested with SqlServer. In fact, the official example let this possibility https://github.com/aspnet/Docs/blob/master/aspnetcore/tutorials/razor-pages/razor-pages-start/2.2-stage-samples/RPmovieSQLiteNewField/Startup.cs .
Maybe, it's normal, because as https://docs.microsoft.com/en-us/ef/core/modeling/keys said, the convention is « By convention, a property named Id or \ Maybe it works on Windows because this system is case insensitive, but maybe doesn't work on Linux because this system is case sensitive. I havn't a Mac, but maybe this problem could occur on Mac as this system is Case sensitive. Actually the output is : Thanks in advance for your answer ! ⚠Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.Microsoft.EntityFrameworkCore.DbUpdateException: An error occurred while updating the entries. See the inner exception for details. ---> System.Data.SqlClient.SqlException: Cannot insert
the value NULL into column 'ID', table 'RazorPageMovie.dbo.Movie'; column does not allow nulls. INSERT fails.
The statement has been terminated.
at System.Data.SqlClient.SqlCommand.<>c.<ExecuteDbDataReaderAsync>b__122_0(Task`1 result)
at System.Threading.Tasks.ContinuationResultTaskFromResultTask`2.InnerInvoke()
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location where exception was thrown ---
at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot)
--- End of stack trace from previous location where exception was thrown ---
at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.ExecuteAsync(IRelationalConnection connection, DbCommandMethod executeMethod, IReadOnlyDictionary`2 parameterValues,
CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.ExecuteAsync(IRelationalConnection connection, CancellationToken cancellationToken)
--- End of inner exception stack trace ---
at Microsoft.EntityFrameworkCore.Update.ReaderModificationCommandBatch.ExecuteAsync(IRelationalConnection connection, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(DbContext _, ValueTuple`2 parameters, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func`4 operation, Func`4 verifySucceeded, Cancellation
Token cancellationToken)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(IReadOnlyList`1 entriesToSave, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync(Boolean acceptAllChangesOnSuccess, CancellationToken cancellationToken)
at RazorPagesMovie.Pages.Movies.CreateModel.OnPostAsync() in /tmp/RazorPagesMovie/RPmovieSQLiteNewField/Pages/Movies/Create.cshtml.cs:line 45
at Microsoft.AspNetCore.Mvc.RazorPages.Internal.ExecutorFactory.GenericTaskHandlerMethod.Convert[T](Object taskAsObject)
at Microsoft.AspNetCore.Mvc.RazorPages.Internal.ExecutorFactory.GenericTaskHandlerMethod.Execute(Object receiver, Object[] arguments)
at Microsoft.AspNetCore.Mvc.RazorPages.Internal.PageActionInvoker.InvokeHandlerMethodAsync()
at Microsoft.AspNetCore.Mvc.RazorPages.Internal.PageActionInvoker.InvokeNextPageFilterAsync()
at Microsoft.AspNetCore.Mvc.RazorPages.Internal.PageActionInvoker.Rethrow(PageHandlerExecutedContext context)
at Microsoft.AspNetCore.Mvc.RazorPages.Internal.PageActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.RazorPages.Internal.PageActionInvoker.InvokeInnerFilterAsync()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResourceFilter()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync()
at Microsoft.AspNetCore.Routing.EndpointMiddleware.Invoke(HttpContext httpContext)
at Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware.Invoke(HttpContext httpContext)
at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
Document Details
An other solution is to add [key] on the line above like this:
[Key]
public int ID { get; set; }
then:
rm -R Migrations
dotnet ef migrations add InitialCreate
dotnet ef database update
@JulioJu you're correct
[Key]
public int ID { get; set; }
works. But it's better to update the tutorial and use Id
We'll do that in the next doc sweep.
Thanks for bringing this to our attention.
@JulioJu let me know if you have any good tips on ASP.NET Core development on Linux
it's better to update the tutorial and use Id
Therefore, under Linux, actually users could trigger:
dotnet ef database drop \
&& rm -Rf Migrations bin obj \
&& find -name "*.cs*" -exec sed -i 's/ID/Id/g' {} + \
&& dotnet ef migrations add InitialCreate \
&& dotnet ef database update \
&& dotnet watch run
Tested, and well check what is changed, work well !
Before trigger this command, you could check what is changed thanks:
$ find -name "*.cs*" -exec grep --color="always" ID {} +
@Rick-Anderson I could make the PR if you want ;-).
@JulioJu thanks for the offer, but it's more complicated with all the code and the docs. We'll get this fixed when we do the 3.0 version.
Thanks again for the offer.
@Rick-Anderson
I've tested again, and our analyses was completely false. Sorry.
I've tested again because as I'm new on dotnet I like to use your out-of-box samples to understand well some concepts. And I've discovered that uppercase ID work fine for Contoso sample. Therefore I've investigated further.
I've believe before that's due to uppercase ID because when I've tested with Id it works, but it works because as you could see in my command I've deleted Migrations files before generated it again (rm -Rf). Sorry !
For:
# See also https://docs.microsoft.com/en-us/aspnet/core/tutorials/razor-pages/new-field?view=aspnetcore-2.2&tabs=visual-studio-code
dotnet ef database drop \
&& rm -Rf Migrations bin obj \
&& cp -r ../RPmovieSearch/Migrations . \
&& dotnet ef database update \
&& dotnet ef migrations add Rating \
&& dotnet ef database update \
&& dotnet watch run
Furthermore I've tested the following command without success for RPMovieNewField.
Following demonstrate that current Migration are completely broken on Linux Platform even if we replace all uppercase ID to Id.
find -name "*.cs*" -exec grep --color="always" ID {} + # to check what will be changed.
dotnet ef database drop \
&& find -name "*.cs*" -exec sed -i 's/ID/Id/g' {} + \
&& dotnet ef database update
If you are ok I could make a PR to generate completely new Migrations files thanks command above for :
I've generated thanks tools dotnet-ef 2.2.1 (the last one today) and dotnet-core 2.2.102
If your are ok,
@Rick-Anderson, for this issue, if I understand it correctly, we can't use "ID" even if we are consistent about it because by the time it gets through migrations and data generation it is treated somewhere as "Id" instead? Is this an issue to also raise for the product migration code?
If I understand what the fix is for the RP series, it is to redo all versions and the sub-variations of app samples (there are a lot in this series) with Id instead of ID, plus of course where it is mentioned in the tutorials?
Just thought I would verify in case the fix is simpler and more isolated than I am understanding it to be. I didn't want to needlessly redo all the previous versions of the app and sub-variations, sdk versions, IDE versions and sub-variations (sqlserver and sqlLite), unless that really is the only avenue. Many thanks for your insight.
I'd put this on hold as we've only had one person report the problem.
@Rick-Anderson, thanks, I was already feeling like I was overloading the RP 5.0 update as it was with the backlog into a rather large and complicated PR with perhaps too many issues at once. This one really needs its own dedicated PR if it moves up in the priority list. It certainly is a n interesting issue though.
Most helpful comment
An other solution is to add [key] on the line above like this:
then: