Closed andregizero closed 6 years ago
Does the dotnet ef dbcontext scaffold
command throw an exception without including the ScaffoldingDesignTimeServices
class in your project? It looks like the error is thrown by EF Core and has nothing to do with the Handlebars templating add-in.
From the message it looks like you simply need to make the IsActive property nullable in both the database and your model. If you still have problems, I suggest you post the issue to the EF Core repo or on Stack Overflow.
If I remove ScaffoldingDesignTimeServices.cs from the project I can run the scaffolding command without any problems. If I add the file back the NullReferenceException occurs again. So it certainly looks like it's triggered by Handlebars.
Would you be able to post a repo to GitHub so I can step through the code?
Unfortunately the code as well as the database belongs to my employer so I cannot share that. Is there a way I can enable tracing or debug this myself?
Let me ask @bricelam: Is there a way to attach the VS debugger to the process running the dotnet ef dbcontext scaffold
command so that we can set breakpoints and step through the code?
@andredahlqvist Could you provide a sample that reproduces your issue but does not use anything proprietary?
Sure, I will try to narrow it down.
To debug, add a call to Debugger.Launch() somewhere in your code, e.g. in your or the app's IDesignTimeServices.ConfigureDesignTimeServices() implementation.
@andredahlqvist If you provide a sample repo, we should be able to debug the error by adding Debugger.Launch() and setting a breakpoint. We can also set VS to break on all exceptions.
Sorry for the delay. Here is a repository that shows how to reproduce the crash. Instructions in the README.md file.
I’ll debug this to what’s happening.
@andredahlqvist There is something wrong with the bak file in your project. After restoring I don't see any tables, and when I try to create a database diagram it says I don't have permission.
Instead of a bak file, can you instead provide a SQL script to create the table?
@tonysneed Actually that's on purpose. I noticed that it didn't matter which tables I had in the database, I could even reproduce it without any tables.
So you're trying to reverse engineer a table that doesn't exist in the database?
@tonysneed I realize that's silly, and it may not be the same crash as I saw when I was actually running against a database with tables, but I assumed the crash could actually be unrelated to the reverse engineering part. Either way, it shouldn't crash when the table you are pointing to doesn't exist.
I thought you were reproducing the original error, which took place with a table that has a column with a default constraint? Is this still the case?
Like I said, it happens no matter what table I try it on. If it makes you feel happier I can send you a bak file with a random table that it crashes on.
I'm just trying to understand how to reproduce the issue. From what you're saying, I simply need to try to reverse engineer a table that does not exist in the database using ReverseEngineerOptions.EntitiesOnly
. Is that correct?
It does crash if I do that and that's the simplest testcase I could come up with. That's why I wrote those instructions in the README.md.
OK so the expected result should be the message: Unable to find a table in the database matching the selected table dummy.
Yeah, that's what I wrote in the README.md (as you can see the crash appears to happen in CheckOutputFiles, just like in the original stack trace I posted in this issue).
You should receive the following stack trace:
Unable to find a table in the database matching the selected table dummy. System.NullReferenceException: Object reference not set to an instance of an object. at Microsoft.EntityFrameworkCore.Scaffolding.Internal.ReverseEngineerScaffolder.CheckOutputFiles(ScaffoldedModel scaffoldedModel, String outputDir, Boolean overwriteFiles) at Microsoft.EntityFrameworkCore.Scaffolding.Internal.ReverseEngineerScaffolder.Save(ScaffoldedModel scaffoldedModel, String outputDir, Boolean overwriteFiles) at Microsoft.EntityFrameworkCore.Design.Internal.DatabaseOperations.ScaffoldContext(String provider, String connectionString, String outputDir, String outputContextDir, String dbContextClassName, IEnumerable1 schemas, IEnumerable1 tables, Boolean useDataAnnotations, Boolean overwriteFiles, Boolean useDatabaseNames) at Microsoft.EntityFrameworkCore.Design.OperationExecutor.ScaffoldContextImpl(String provider, String connectionString, String outputDir, String outputDbContextDir, String dbContextClassName, IEnumerable1 schemaFilters, IEnumerable1 tableFilters, Boolean useDataAnnotations, Boolean overwriteFiles, Boolean useDatabaseNames) at Microsoft.EntityFrameworkCore.Design.OperationExecutor.ScaffoldContext.<>cDisplayClass0_1.<.ctor>b0() at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.<>cDisplayClass3_0`1.b0() at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action) Object reference not set to an instance of an object.
_
OK, I was confused because in your original post you were not specifying a table. Were you able to resolve that issue?
The crash happens in the same method so I believe this is the same issue.
But can you reproduce the issue with an existing table? I don't think it has anything to do with whether the table exists or not.
Feel like I'm repeating myself: it happens no matter what table I try it on, i.e. existing tables too.
I understand now. Your repro would be clearer if you would not introduce the variable of the non-existent table. That would save me time in troubleshooting.
Fixed by PR #24. I'll include this with release v1.1.0.
I'm using .NET Core 2.1.300-rc1-008673 and have updated to 1.0.0-rc3 of EntityFrameworkCore.Scaffolding.Handlebars. I get the following NullPointer when trying to scaffold from an existing database. I have previously used 1.0.0-beta together with .NET Core 2.0 and have successfully scaffolded using the same database.
Unable to generate entity type for table 'dbo.SavedRadioButtons'. The column 'dbo.NoteResources.IsActive' would normally be mapped to a non-nullable bool property, but it has a default constraint. Such a column is mapped to a nullable bool property to allow a difference between setting the property to false and invoking the default constraint. See https://go.microsoft.com/fwlink/?linkid=851278 for details. System.NullReferenceException: Object reference not set to an instance of an object. at Microsoft.EntityFrameworkCore.Scaffolding.Internal.ReverseEngineerScaffolder.CheckOutputFiles(ScaffoldedModel scaffoldedModel, String outputDir, Boolean overwriteFiles) at Microsoft.EntityFrameworkCore.Scaffolding.Internal.ReverseEngineerScaffolder.Save(ScaffoldedModel scaffoldedModel, String outputDir, Boolean overwriteFiles) at Microsoft.EntityFrameworkCore.Design.Internal.DatabaseOperations.ScaffoldContext(String provider, String connectionString, String outputDir, String outputContextDir, String dbContextClassName, IEnumerableb 0()
at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
Object reference not set to an instance of an object.
1 schemas, IEnumerable
1 tables, Boolean useDataAnnotations, Boolean overwriteFiles, Boolean useDatabaseNames) at Microsoft.EntityFrameworkCore.Design.OperationExecutor.ScaffoldContextImpl(String provider, String connectionString, String outputDir, String outputDbContextDir, String dbContextClassName, IEnumerable1 schemaFilters, IEnumerable
1 tableFilters, Boolean useDataAnnotations, Boolean overwriteFiles, Boolean useDatabaseNames) at Microsoft.EntityFrameworkCore.Design.OperationExecutor.ScaffoldContext.<>cDisplayClass0_1.<.ctor>b0() at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.<>cDisplayClass3_0`1.I'm using the following command:
dotnet ef dbcontext scaffold "Data Source=localhost;Initial Catalog=MyDatabase;User Id=secret; Password=secret" Microsoft.EntityFrameworkCore.SqlServer -o Domain -c MyDbContext -f