7

I am working on an MVC 4 project that use EF 6 for all operations to and from the Database (SQL Server). I had to do some refactoring to use a more explicit Fluent API. Basically, now every entity on the project has its corresponding Fluent API code for all mappings.

The problem comes when I try to run the EF commands from Package Manager Console. This is the error I am getting: The store type 'Varchar(100)' could not be found in the SqlServer provider manifest

This is the complete log of the error:

PM> enable-migrations
Checking if the context targets an existing database...
System.InvalidOperationException: The store type 'Varchar(100)' could not be found in the SqlServer provider manifest
   at System.Data.Entity.Utilities.DbProviderManifestExtensions.GetStoreTypeFromName(DbProviderManifest providerManifest, String name)
   at System.Data.Entity.ModelConfiguration.Configuration.Properties.Primitive.PrimitivePropertyConfiguration.ConfigureColumn(EdmProperty column, EntityType table, DbProviderManifest providerManifest)
   at System.Data.Entity.ModelConfiguration.Configuration.Properties.Primitive.PrimitivePropertyConfiguration.<>c__DisplayClass47_0.<Configure>b__0(Tuple`2 pm)
   at System.Data.Entity.Utilities.IEnumerableExtensions.Each[T](IEnumerable`1 ts, Action`1 action)
   at System.Data.Entity.ModelConfiguration.Configuration.Types.StructuralTypeConfiguration.ConfigurePropertyMappings(IList`1 propertyMappings, DbProviderManifest providerManifest, Boolean allowOverride)
   at System.Data.Entity.ModelConfiguration.Configuration.Types.EntityTypeConfiguration.ConfigurePropertyMappings(DbDatabaseMapping databaseMapping, EntityType entityType, DbProviderManifest providerManifest, Boolean allowOverride)
   at System.Data.Entity.ModelConfiguration.Configuration.Types.EntityTypeConfiguration.Configure(EntityType entityType, DbDatabaseMapping databaseMapping, DbProviderManifest providerManifest)
   at System.Data.Entity.ModelConfiguration.Configuration.ModelConfiguration.ConfigureEntityTypes(DbDatabaseMapping databaseMapping, ICollection`1 entitySets, DbProviderManifest providerManifest)
   at System.Data.Entity.ModelConfiguration.Configuration.ModelConfiguration.Configure(DbDatabaseMapping databaseMapping, DbProviderManifest providerManifest)
   at System.Data.Entity.DbModelBuilder.Build(DbProviderManifest providerManifest, DbProviderInfo providerInfo)
   at System.Data.Entity.DbModelBuilder.Build(DbConnection providerConnection)
   at System.Data.Entity.Internal.LazyInternalContext.CreateModel(LazyInternalContext internalContext)
   at System.Data.Entity.Internal.RetryLazy`2.GetValue(TInput input)
   at System.Data.Entity.Internal.LazyInternalContext.InitializeContext()
   at System.Data.Entity.Internal.LazyInternalContext.get_ModelBeingInitialized()
   at System.Data.Entity.Infrastructure.EdmxWriter.WriteEdmx(DbContext context, XmlWriter writer)
   at System.Data.Entity.Utilities.DbContextExtensions.GetModel(Action`1 writeXml)
   at System.Data.Entity.Migrations.DbMigrator..ctor(DbMigrationsConfiguration configuration, DbContext usersContext, DatabaseExistenceState existenceState, Boolean calledByCreateDatabase)
   at System.Data.Entity.Migrations.DbMigrator..ctor(DbMigrationsConfiguration configuration)
   at System.Data.Entity.Migrations.Design.MigrationScaffolder..ctor(DbMigrationsConfiguration migrationsConfiguration)
   at System.Data.Entity.Infrastructure.Design.Executor.CreateMigrationScaffolder(DbMigrationsConfiguration configuration)
   at System.Data.Entity.Infrastructure.Design.Executor.ScaffoldInitialCreateInternal(DbConnectionInfo connectionInfo, String contextTypeName, String contextAssemblyName, String migrationsNamespace, Boolean auto, String migrationsDir)
   at System.Data.Entity.Infrastructure.Design.Executor.ScaffoldInitialCreate.<>c__DisplayClass0_0.<.ctor>b__0()
   at System.Data.Entity.Infrastructure.Design.Executor.OperationBase.<>c__DisplayClass4_0`1.<Execute>b__0()
   at System.Data.Entity.Infrastructure.Design.Executor.OperationBase.Execute(Action action)

I have been reading a lot of blogs/ post how to solve this but none of them seems to work. These are a few things I have tried:

  1. Reinstalling EntityFramework.dll and EntityFrameWork.SqlServer.dll
  2. Adding a dummy method to explicitly load the assembly. This is the link
  3. Originally I was using EF 6.3.0 and upgraded to EF 6.4.0. I thought the upgrade was the problem so I downgraded but still having the same issue.

Updated This is the code for the Entity:

public class EntityA: BaseEntity
    {
        /// <summary>
        /// Gets or sets Contact identifier
        /// </summary>
        public int Id { get; set; }

        public string Name { get; set; }

        public string Description { get; set; }

        public bool IsActive { get; set; }
}

Using Fluent API configuration in a separated class:

public class EntityAConfiguration : EntityTypeConfiguration<EntityA>
    {
        public EntityAConfiguration()
        {
            this.ToTable("EntityA")
                .HasKey(c => c.Id);

            this.Property(c => c.Id)
                .HasColumnName("Id")
                .HasColumnType("int")
                .IsRequired();

            this.Property(c => c.Name)
                .HasColumnName("Name")
                .HasColumnType("Varchar(40)")
                .IsRequired();

            this.Property(c => c.Description)
                .HasColumnName("Description")
                .HasColumnType("Varchar(100)")
                .IsRequired();

            this.Property(c => c.IsActive)
                .HasColumnName("IsActive")
                .HasColumnType("bit");
        }
    }

BaseEntity class is only having two properties: CreatedDate, UpdatedDate. I use that class in all Entities that needs to store that info.

At this point I am running out of ideas how to solve this. If any one has face a similar problem I would really appreciate if you can help or point me to any information that could help.

MikePR
  • 2,786
  • 5
  • 31
  • 64
  • 1
    `I had to do some refactoring to use a more explicit Fluent API` could you perhaps show us an example we could replicate to help you? – Trevor Mar 23 '20 at 14:45
  • @Çöđěxěŕ, post updated. – MikePR Mar 23 '20 at 15:08
  • 1
    Try `this.Property(e => e.Name).HasColumnType("VARCHAR").HasMaxLength(40);` and so on... this is a more fluent API approach. The `HasColumnType` doesn't take length... – Trevor Mar 23 '20 at 15:19

2 Answers2

8

This is the error I am getting: The store type 'Varchar(100)' could not be found in the SqlServer provider manifest

This is because it's invalid, as mentioned in my comment above, you can't pass the length of the type in HasColumnType. To fix this please see below.

public EntityAConfiguration()
        {
            this.ToTable("EntityA")
                .HasKey(c => c.Id);

            this.Property(c => c.Id)
                .HasColumnName("Id")
                .HasColumnType("INT")
                .IsRequired();

            this.Property(c => c.Name)
                .HasColumnName("Name")
                .HasColumnType("VARCHAR")
                .HasMaxLength(40)
                .IsRequired();

            this.Property(c => c.Description)
                .HasColumnName("Description")
                .HasColumnType("VARCHAR")
                .HasMaxLength(100)
                .IsRequired();

            this.Property(c => c.IsActive)
                .HasColumnName("IsActive")
                .HasColumnType("bit");
        }

You will now see a new property called HasMaxLength, this is where you define the length. The HasColumnType is only the type definition, nothing more.

Trevor
  • 7,777
  • 6
  • 31
  • 50
  • 1
    I just did that change on my configuration class and it worked. I was trying to implement it the same way as it works in EF Core but looks like in EF 6 that approach is not supported. Thanks to pointed me out to the correct direction – MikePR Mar 23 '20 at 18:44
1

Of course, this is a matter of taste, but I prefer the option using attributes. In this case, all the code is in one place.

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

public class EntityA: BaseEntity
{
    /// <summary>
    /// Gets or sets Contact identifier
    /// </summary>
    public int Id { get; set; }

    [Column(TypeName = "VARCHAR")]
    [StringLength(40)]
    public string Name { get; set; }

    [Column(TypeName = "VARCHAR")]
    [StringLength(100)]
    public string Description { get; set; }

    public bool IsActive { get; set; }
}
Igor Nedbaylo
  • 101
  • 1
  • 3