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

SqlServer: Char mapping worked in 1.1 but does not work in 2.0 #9447

Closed
jbt00000 opened this issue Aug 17, 2017 · 13 comments
Closed

SqlServer: Char mapping worked in 1.1 but does not work in 2.0 #9447

jbt00000 opened this issue Aug 17, 2017 · 13 comments

Comments

@jbt00000
Copy link

After upgrading from EF 1.1 to 2.0, EF has problem validating model. This is data first and uses attributes.

Definition was...

	[Column("XXXXX")]
	public char XXXXX{ get; set; }
System.InvalidOperationException occurred
  HResult=0x80131509
  Message=The property 'XXXXX' could not be mapped, because it is of type 'char' which is not a supported primitive type or a valid entity type. Either explicitly map this property, or ignore it using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.
  Source=<Cannot evaluate the exception source>
  StackTrace:
   at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.PropertyMappingValidationConvention.Apply(InternalModelBuilder modelBuilder)
   at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionDispatcher.ImmediateConventionScope.OnModelBuilt(InternalModelBuilder modelBuilder)
   at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionDispatcher.OnModelBuilt(InternalModelBuilder modelBuilder)
   at Microsoft.EntityFrameworkCore.Metadata.Internal.Model.Validate()
   at Microsoft.EntityFrameworkCore.Metadata.Internal.InternalModelBuilder.Validate()
   at Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.CreateModel(DbContext context, IConventionSetBuilder conventionSetBuilder, IModelValidator validator)
   at Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.<>c__DisplayClass5_0.<GetModel>b__0(Object k)
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
   at Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.GetModel(DbContext context, IConventionSetBuilder conventionSetBuilder, IModelValidator validator)
   at Microsoft.EntityFrameworkCore.Internal.DbContextServices.CreateModel()
   at Microsoft.EntityFrameworkCore.Internal.DbContextServices.get_Model()
   at Microsoft.EntityFrameworkCore.Infrastructure.EntityFrameworkServicesBuilder.<>c.<TryAddCoreServices>b__7_1(IServiceProvider p)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite, ServiceProvider provider)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite, ServiceProvider provider)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, ServiceProvider provider)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite, ServiceProvider provider)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.<>c__DisplayClass22_0.<RealizeService>b__0(ServiceProvider provider)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
   at Microsoft.EntityFrameworkCore.DbContext.get_DbContextDependencies()
   at Microsoft.EntityFrameworkCore.DbContext.get_InternalServiceProvider()
   at Microsoft.EntityFrameworkCore.DbContext.get_DbContextDependencies()
   at Microsoft.EntityFrameworkCore.DbContext.Microsoft.EntityFrameworkCore.Internal.IDbContextDependencies.get_EntityFinderSource()
   at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.get_Finder()
   at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.FindAsync(Object[] keyValues)
   at Traffk.Bal.Services.CurrentTenantServices.<GetTenantAsync>d__4.MoveNext() in C:\src\traffk\HealthInformationPortal\src\Traffk.Bal\Services\CurrentTenantServices.cs:line 27

@ajcvickers
Copy link
Contributor

@jbt00000 Which database provider are you using?

@jbt00000
Copy link
Author

I'm going against Sql Azure

@jbt00000
Copy link
Author

In the short term, I've converted my tt file to change the mapping to string. which is not great as there is no not null support, but acceptable in the short term.

@ChristopherRobinSuperStar
Copy link

ChristopherRobinSuperStar commented Aug 17, 2017

I have the same truble when start Scaffold-DbContext command after updating to core 2.0. But I get the next exception "ArgumentException: Data type 'nvarchar' is not supported in this form. Either specify the length explicitly in the type name, for example as 'nvarchar(16)', or remove the data type and use APIs such as HasMaxLength to allow EF choose the data type." For example part of generated code
entity.Property(e => e.Name) .IsRequired() .HasColumnName("NAME") .HasMaxLength(30);

DB SQL Server 2016 Express. All had worked fine before I started Scaffold-DbContext command after updating to Core 2.0 and VS to 15.3 version. Please help me(

ArgumentException: Data type 'nvarchar' is not supported in this form. Either specify the length explicitly in the type name, for example as 'nvarchar(16)', or remove the data type and use APIs such as HasMaxLength to allow EF choose the data type.
Microsoft.EntityFrameworkCore.Storage.Internal.SqlServerTypeMapper.ValidateTypeName(string storeType)
Microsoft.EntityFrameworkCore.Infrastructure.RelationalModelValidator.ValidateDataTypes(IModel model)
Microsoft.EntityFrameworkCore.Infrastructure.RelationalModelValidator.Validate(IModel model)
Microsoft.EntityFrameworkCore.Internal.SqlServerModelValidator.Validate(IModel model)
Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.CreateModel(DbContext context, IConventionSetBuilder conventionSetBuilder, IModelValidator validator)
Microsoft.EntityFrameworkCore.Infrastructure.ModelSource+<>c__DisplayClass5_0.b__0(object k)
System.Collections.Concurrent.ConcurrentDictionary.GetOrAdd(TKey key, Func<TKey, TValue> valueFactory)
Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.GetModel(DbContext context, IConventionSetBuilder conventionSetBuilder, IModelValidator validator)
Microsoft.EntityFrameworkCore.Internal.DbContextServices.CreateModel()
Microsoft.EntityFrameworkCore.Internal.DbContextServices.get_Model()
Microsoft.EntityFrameworkCore.Infrastructure.EntityFrameworkServicesBuilder+<>c.b__7_1(IServiceProvider p)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite, ServiceProvider provider)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor.VisitCallSite(IServiceCallSite callSite, TArgument argument)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite, ServiceProvider provider)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor.VisitCallSite(IServiceCallSite callSite, TArgument argument)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, ServiceProvider provider)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor.VisitCallSite(IServiceCallSite callSite, TArgument argument)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite, ServiceProvider provider)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor.VisitCallSite(IServiceCallSite callSite, TArgument argument)
Microsoft.Extensions.DependencyInjection.ServiceProvider+<>c__DisplayClass22_0.b__0(ServiceProvider provider)
Microsoft.Extensions.DependencyInjection.ServiceProvider.GetService(Type serviceType)
Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider)
Microsoft.EntityFrameworkCore.DbContext.get_DbContextDependencies()
Microsoft.EntityFrameworkCore.DbContext.get_InternalServiceProvider()
Microsoft.EntityFrameworkCore.DbContext.get_DbContextDependencies()
Microsoft.EntityFrameworkCore.DbContext.get_Model()
Microsoft.EntityFrameworkCore.Internal.InternalDbSet.get_EntityType()
Microsoft.EntityFrameworkCore.Internal.InternalDbSet.get_EntityQueryable()
Microsoft.EntityFrameworkCore.Internal.InternalDbSet.Microsoft.EntityFrameworkCore.Query.Internal.IAsyncEnumerableAccessor.get_AsyncEnumerable()
Microsoft.EntityFrameworkCore.Extensions.Internal.QueryableExtensions.AsAsyncEnumerable(IQueryable source)
Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync(IQueryable source, CancellationToken cancellationToken)

@smitpatel
Copy link
Contributor

@jbt00000 - It is breaking change see #8656

@ChristopherRobinSuperStar - Please file a new issue since it is unrelated to issue reported here.

@smitpatel smitpatel changed the title worked in 1.1 fails in 2.0 - char mapping SqlServer: Char mapping worked in 1.1 but does not work in 2.0 Aug 17, 2017
@jbt00000
Copy link
Author

That's fine, the change was fairly minor in my custom tt file.

That said, if there is not a "Look at the breaking changes between EF 1.1 and EF 2.0" page, there should be one and this should make the list.

@ChristopherRobinSuperStar

But what should I do with my breaked varchar mapping?

@ajcvickers
Copy link
Contributor

@jbt00000 Curious: in 1.1, was the char property being populated with the correct value from the database when running a query? What is the column type in the database?

@jbt00000
Copy link
Author

it was a

char(1) not null

And... the best I can say is that nobody had reported a bug on that value...

I have a custom TT file that had changed that type into a char, as such, the change on my side was pretty trivial once I understood this to be a permanent change.

@ajcvickers
Copy link
Contributor

Re-opening this to investigate if this should be added back--we had previously thought the the 1.1 mapping we had was broken, but if it is not, then we should add it back.

@smitpatel
Copy link
Contributor

There is no suitable mapping for char property in SqlServer.

Saving data is fine for either mapping of int or char(1). Since SqlServer does not have native char mapping value will be stored in database as int & string (of size 1) respectively, When you read back data, assigning value of int/string to char throws InvalidCastException.

Furthermore, with char(1) mapping writing any query involving property also causes error. By default c# compiler converts char constants to int and put a convert around char property. When we generate SQL for that we would print int literal, if the column type is char(1) then it is invalid SQL. This kind of conversion is out of control of EF and done by C# compiler.

In either case, reading data is char property is not possible so we should disallow mapping char property in SqlServer till we have type conversions in #242

@smitpatel
Copy link
Contributor

Removing regression since, saving data always worked but querying data was faulty. Reading back data does not work in 1.1.2 or 2.0.0 so it is not regression.

@ajcvickers - Should we close this now? (what should be labels?)

@ajcvickers ajcvickers removed this from the 2.1.0 milestone Oct 6, 2017
@smiller781
Copy link

This is not good man.
What are we supposed to do if we don't have control of the DB. This should just map. What a headache.

@ajcvickers ajcvickers closed this as not planned Won't fix, can't repro, duplicate, stale Oct 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants