Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The 'OpenEdgeBoolTypeMapping' does not support value conversions. #10

Open
Alfetta159 opened this issue Aug 28, 2019 · 10 comments
Open
Assignees
Labels
bug Something isn't working

Comments

@Alfetta159
Copy link

When I run the Scaffold-DbContext cmdlet, I get the following error.

The 'OpenEdgeBoolTypeMapping' does not support value conversions. Support for value conversions typically requires changes in the database provider.

I'm not familiar with creating a db context provider. How do you debug one. Is it a matter of running the edmgen.exe or does that not work with .NET core?

More info:

Scaffold-DbContext "dsn=mydata;password=password1" EntityFrameworkCore.OpenEdge -StartupProject 'MyApi' -OutputDir Data
System.NotImplementedException: The 'OpenEdgeBoolTypeMapping' does not support value conversions. Support for value conversions typically requires changes in the database provider.
   at Microsoft.EntityFrameworkCore.Storage.RelationalTypeMapping.Clone(RelationalTypeMappingInfo& mappingInfo)
   at EntityFrameworkCore.OpenEdge.Storage.Internal.Mapping.OpenEdgeTypeMappingSource.FindMapping(RelationalTypeMappingInfo& mappingInfo)
   at Microsoft.EntityFrameworkCore.Storage.RelationalTypeMappingSource.<FindMappingWithConversion>b__7_0(ValueTuple`3 k)
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
   at Microsoft.EntityFrameworkCore.Storage.RelationalTypeMappingSource.FindMappingWithConversion(RelationalTypeMappingInfo& mappingInfo, IReadOnlyList`1 principals)
   at Microsoft.EntityFrameworkCore.Storage.RelationalTypeMappingSource.FindMapping(String storeTypeName)
   at Microsoft.EntityFrameworkCore.Scaffolding.Internal.ScaffoldingTypeMapper.FindMapping(String storeType, Boolean keyOrIndex, Boolean rowVersion)
   at Microsoft.EntityFrameworkCore.Scaffolding.Internal.RelationalScaffoldingModelFactory.GetTypeScaffoldingInfo(DatabaseColumn column)
   at Microsoft.EntityFrameworkCore.Scaffolding.Internal.RelationalScaffoldingModelFactory.VisitColumn(EntityTypeBuilder builder, DatabaseColumn column)
   at Microsoft.EntityFrameworkCore.Scaffolding.Internal.RelationalScaffoldingModelFactory.VisitColumns(EntityTypeBuilder builder, ICollection`1 columns)
   at Microsoft.EntityFrameworkCore.Scaffolding.Internal.RelationalScaffoldingModelFactory.VisitTable(ModelBuilder modelBuilder, DatabaseTable table)
   at Microsoft.EntityFrameworkCore.Scaffolding.Internal.RelationalScaffoldingModelFactory.VisitTables(ModelBuilder modelBuilder, ICollection`1 tables)
   at Microsoft.EntityFrameworkCore.Scaffolding.Internal.RelationalScaffoldingModelFactory.VisitDatabaseModel(ModelBuilder modelBuilder, DatabaseModel databaseModel)
   at Microsoft.EntityFrameworkCore.Scaffolding.Internal.RelationalScaffoldingModelFactory.Create(DatabaseModel databaseModel, Boolean useDatabaseNames)
   at Microsoft.EntityFrameworkCore.Scaffolding.Internal.ReverseEngineerScaffolder.ScaffoldModel(String connectionString, IEnumerable`1 tables, IEnumerable`1 schemas, String namespace, String language, String contextDir, String contextName, ModelReverseEngineerOptions modelOptions, ModelCodeGenerationOptions codeOptions)
   at Microsoft.EntityFrameworkCore.Design.Internal.DatabaseOperations.ScaffoldContext(String provider, String connectionString, String outputDir, String outputContextDir, String dbContextClassName, IEnumerable`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, IEnumerable`1 schemaFilters, IEnumerable`1 tableFilters, Boolean useDataAnnotations, Boolean overwriteFiles, Boolean useDatabaseNames)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.ScaffoldContext.<>c__DisplayClass0_1.<.ctor>b__0()
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.<>c__DisplayClass3_0`1.<Execute>b__0()
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
The 'OpenEdgeBoolTypeMapping' does not support value conversions. Support for value conversions typically requires changes in the database provider.
@alexwiese
Copy link
Owner

alexwiese commented Aug 28, 2019

Hey @Alfetta159

Can you please confirm the versions of these packages that you're using?

  • Microsoft.EntityFrameworkCore
  • Microsoft.EntityFrameworkCore.Relational
  • EntityFrameworkCore.OpenEdge

You should have 2.1.11 for the EF Core packages and 1.0.8 for the EntityFrameworkCore.OpenEdge.

If you try to use a newer, unsupported version of EF Core it can cause issues.

Also can you please let me know if you're trying to map a LOGICAL field to something other than bool or bool?
Note that if an OpenEdge field is not marked as Mandatory then it will need to be mapped to a nullable type in your Entity.
Eg. a non-Mandatory LOGICAL in OpenEdge <=> bool? in .NET

@Alfetta159
Copy link
Author

EntityFrameworkCore.OpenEdge 1.0.8
Microsoft.EntityFrameworkCore 2.2.6
Microsoft.EntityFrameworkCore.Relational 2.2.6

I realize these are forward of the requirement, but I have checked it with the 2.1.11 versions and I get the same result.

Keep in mind that I am not trying to map anything. I'm using the Scaffolding cmdlet to generate the database context and models, so I'm expecting the database provider to do that mapping.

Again: I'm not familiar with creating a db context provider. How do you debug one? Is it a matter of running the edmgen.exe or does that not work with .NET core? If you would enlighten me, I could give you better information as to the types/fields the provider is finding in my database (which is a third party database) and how it's having trouble.

Thx again!

@alexwiese
Copy link
Owner

OK that is interesting. I haven't had this problem before and I have scaffolded large databases before.
I'm not sure if there is an easy way to debug it as it's a part of the actual EF Core tooling, the provider essentially just generates the metadata used by the EF Core tooling.
Is there a way you can trace it down to a specific table and/or column that might be causing the issue?
I'll take a look at the boolean/logical type mapping code on my side and see if there is anything obvious.

@alexwiese
Copy link
Owner

Are you able to run this SQL statement against the database and send me the result? It will return a record set of the datatypes used by the fields in your database. There may be a datatype that you're using that's tripping up the model generator that I'm not using myself.

SELECT "_Data-Type" FROM pub."_Field" GROUP BY "_Data-Type"

@Alfetta159
Copy link
Author

_Data-Type
character
date
integer
decimal
logical
raw
recid
datetime-tz
int64
blob
fixchar
short
timestamp
double
time
float
bigint
clob
datetime

@alexwiese
Copy link
Owner

hey @Alfetta159

I believe I've found the issue - I was able to reproduce the problem when I was using a version of the EF Core design-time tools that was newer than 2.1.11.
I believe when you tested with version 2.1.11 Visual Studio/Package Manager was actually still using the incorrect version of the design-time tools assembly (Microsoft.EntityFrameworkCore.Design).
Can you please remove EntityFrameworkCore.OpenEdge as well as all of the Microsoft.EntityFrameworkCore packages from your project, then re-add EntityFrameworkCore.OpenEdge (version 1.0.8 or newer). This should automatically add EF Core 2.1.11 to the project.
Then restart VS to make sure the right version of the design assembly is loaded, then try the scaffold again.

I am planning on updating the provider to version 2.2.6 when I get some free time, but for now please ensure all EF Core packages are version 2.1.11

Thanks!

@Alfetta159
Copy link
Author

You're right. I set up a test project based on .Net Core 2.1 with the 2.1.11 EF libraries and it worked much better, but...

There are still a lot of warnings. I've condensed them down and removed table and column names. I did notice that a lot of these are missing from the OpenEdgeTypeMappingSource constructor when I was poking around earlier. Here is the abbreviated list:

Could not find type mapping for column '' with data type 'recid'. Skipping column.
Could not scaffold the primary key for ''. The following columns in the primary key could not be scaffolded: _Cp-Dbrecid.
Unable to generate entity type for table ''.
Could not find type mapping for column '' with data type 'blob'. Skipping column.
The column '' 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.
Could not scaffold the primary key for ''. The following columns in the primary key could not be scaffolded: _Db-recid.
Unable to generate entity type for table ''.
Could not scaffold the primary key for ''. The following columns in the primary key could not be scaffolded: _Con-recid.
Unable to generate entity type for table ''.
The column '' 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.
The column '' 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.
Could not scaffold the primary key for 'pub._Db-Option'. The following columns in the primary key could not be scaffolded: _Db-recid.
Unable to generate entity type for table 'pub._Db-Option'.
The column '' 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.
The column '' 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.
Could not scaffold the primary key for ''. The following columns in the primary key could not be scaffolded: _File-recid.
Unable to generate entity type for table ''.
The column '' 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.
Could not scaffold the primary key for ''. The following columns in the primary key could not be scaffolded: _File-Recid.
Unable to generate entity type for table ''.
The column '' 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.
Could not scaffold the primary key for ''. The following columns in the primary key could not be scaffolded: _File-Recid.
Unable to generate entity type for table ''.
The column '' 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.
Could not scaffold the primary key for ''. The following columns in the primary key could not be scaffolded: _File-recid.
Unable to generate entity type for table ''.
The column '' 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.
The column '' 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.
The column '' 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.
Could not scaffold the primary key for 'pub._Index-Field'. The following columns in the primary key could not be scaffolded: _Index-recid.
Unable to generate entity type for table 'pub._Index-Field'.
The column '' 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.
The column '' 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.
Could not scaffold the primary key for 'pub._Sequence'. The following columns in the primary key could not be scaffolded: _Db-recid.
Unable to generate entity type for table 'pub._Sequence'.
The column '' 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.
Could not scaffold the primary key for 'pub._StorageObject'. The following columns in the primary key could not be scaffolded: _Db-recid.
Unable to generate entity type for table 'pub._StorageObject'.
Could not find type mapping for column '' with data type 'double'. Skipping column.
Could not find type mapping for column '' with data type 'fixchar'. Skipping column.
The column '' 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.
Could not find type mapping for column '' with data type 'blob'. Skipping column.
Could not find type mapping for column '' with data type 'clob'. Skipping column.

@alexwiese
Copy link
Owner

hey - I found that as well and already fixed the blob, double, and recid - they weren't mapped properly.
I have released 1.0.9-rc1 and it will work with those types, as well as clob (it is a pre-release nuget package so make sure you choose pre-release option if searching within VS).
If it works for you I will promote it to 1.0.9 full release version.
The fixchar you can ignore, it's not actually usable from SQL - it's an internal OpenEdge thing.
The other warning you can ignore as it's to do with nullable bool having a default value (see more info here and here)
You will also notice it scaffolds internal tables as well (those starting with _) - I am looking at ways to control that, but for now scaffolding everything is better than a subset, and you can always delete those internal ones from your model once scaffolded.

@Alfetta159
Copy link
Author

That does work much better, thank you. Let me use it a bit more for a day or two before you RTM.

TL;DR My real challenge here is using a third-party enterprise application that doesn't have a proper API: SOAP, REST, Odata or otherwise.

We do have an SSIS project that replicates this data or at least the data that we really need into SQL Server, but that's not real time, and the SSIS project was created w/o considering EF and scaffolding so almost no SQL server tables has a key field and therefore EF to SQL Server can't generate the many tables this db has (nearly 2000). Likewise, most of the real data comes out of views which is still feasible with EF, but very tedious as they can't be scaffolded. Also, many of those views are used for something else, so I end up really needing to write my own views so I don't break something else.

Here, I'm hoping to scaffold the tables that I need into an EF library, and then expose that thru an odata API so my other business APIs can just query for what they need in real-time, but my Oauth2 middleware is written in .NET Core 2.2, so I might have to use this with a pass-thru proxy that worries about auth until this library is updated to 2.2.

@alexwiese
Copy link
Owner

OK great. That’s pretty much what we’re doing in production but closer to 400 tables. There are issues/quirks with the way the OE SQL agent behaves; most of the work in creating this provider was to workaround those issues. Simple SQL queries work well but the more complex ones that EF Core generates could sometimes cause issues.

I have a branch prerelease/1.0.10 that targets 2.2.x which you can try out in your project while targeting .NET Core 2.2 as well. I have fixed a few issues relating to the migration to 2.2 but there are still a couple of issues remaining related to parameters, which can be tricky to diagnose. Once I have those sorted it should be good for 2.2.

@alexwiese alexwiese changed the title he 'OpenEdgeBoolTypeMapping' does not support value conversions. The 'OpenEdgeBoolTypeMapping' does not support value conversions. Sep 1, 2019
@alexwiese alexwiese added the bug Something isn't working label Sep 2, 2019
@alexwiese alexwiese self-assigned this Sep 2, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants