Puse mis modelos en una biblioteca de clase con Core. Ya hice la primera migración para probar una parte de mi modelo, pero después de una gran mejora, eliminé mi base de datos y la migración para tener solo una migración V1.

El problema es que, después de esta eliminación, cuando intento add-migration aparece este error:

System.InvalidOperationException: The entity type 'CustomAttributeData' requires a primary key to be defined.
   at Microsoft.EntityFrameworkCore.Internal.ModelValidator.ShowError(String message)
   at Microsoft.EntityFrameworkCore.Internal.ModelValidator.Validate(IModel model)
   at Microsoft.EntityFrameworkCore.Internal.RelationalModelValidator.Validate(IModel model)
   at Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.CreateModel(DbContext context, IConventionSetBuilder conventionSetBuilder, IModelValidator validator)
   at System.Collections.Concurrent.ConcurrentDictionary`2.GetOrAdd(TKey key, Func`2 valueFactory)
   at Microsoft.EntityFrameworkCore.Internal.DbContextServices.CreateModel()
   at Microsoft.EntityFrameworkCore.Internal.LazyRef`1.get_Value()
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite, ServiceProvider provider)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.<>c__DisplayClass16_0.<RealizeService>b__0(ServiceProvider provider)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetService[T](IServiceProvider provider)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitTransient(TransientCallSite transientCallSite, ServiceProvider provider)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, ServiceProvider provider)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitTransient(TransientCallSite transientCallSite, ServiceProvider provider)
   at Microsoft.Extensions.DependencyInjection.ServiceProvider.<>c__DisplayClass16_0.<RealizeService>b__0(ServiceProvider provider)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
   at Microsoft.EntityFrameworkCore.Design.Internal.MigrationsOperations.AddMigration(String name, String outputDir, String contextType)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.AddMigrationImpl(String name, String outputDir, String contextType)
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.<>c__DisplayClass3_0`1.<Execute>b__0()
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
The entity type 'CustomAttributeData' requires a primary key to be defined.

No sé por qué recibo este error. Todos mis modelos tienen una clave principal definida con DataAnnotation.

Si es necesario, puedo proporcionar los nuevos modelos.

Aquí está el contexto si está relacionado / útil:

public class AmcContext : DbContext
{
    public DbSet<User> Users { get; set; }
    public DbSet<Location> Location { get; set; }
    public DbSet<Rating> Rating { get; set; }
    public DbSet<RatingType> RatingType { get; set; }
    public DbSet<Subscription> Subscription { get; set; }
    public DbSet<Module> Module { get; set; }

    public AmcContext(): base()
    {

    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Ignore<User>();
        modelBuilder.Entity<Client>().ToTable("Client");
        modelBuilder.Entity<Professionnal>().ToTable("Professional");

        base.OnModelCreating(modelBuilder);
    }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer(@"Server=localhost\SQLEXPRESS;Database=Askmycar;Trusted_Connection=True;");

        base.OnConfiguring(optionsBuilder);
    }
}

Gracias.

1
OrcusZ 24 dic. 2016 a las 19:09

3 respuestas

La mejor respuesta

En uno de mis modelos tengo una propiedad como esa:

public Type AvailableFor { get; set; } 

El tipo es un objeto, por lo que estaba esperando una clave primaria. Lo cambio a:

public string AvailableFor { get; set; } 

Y sus obras

Gracias a @ H.Herzi :)

6
OrcusZ 25 dic. 2016 a las 11:00

Para reducir un error mal escrito en su código de EF Core, puede usar una herramienta generadora de código, EF Core tiene una herramienta de línea de comando para la generación de código, en mi caso uso CatFactory y con un código como este podemos generar código de la base de datos existente:

var connectionString = "server=(local);database=Store;integrated security=yes;";

var dbFactory = new SqlServerDatabaseFactory()
{
    ConnectionString = connectionString
};

var db = dbFactory.Import();

var project = new EfCoreProject()
{
    Name = "Store",
    Database = db,
    OutputDirectory = "C:\\Temp\\Store"
};

project.BuildFeatures();

project
    .GenerateEntities()
    .GenerateAppSettings()
    .GenerateMappingDependences()
    .GenerateMappings()
    .GenerateDbContext()
    .GenerateContracts()
    .GenerateRepositories();

Puede obtener más información en este enlace: Generando Código para EF Core con CatFactory

De esa forma evitamos cometer un error al escribir el código de EF Core

1
H. Herzl 25 dic. 2016 a las 17:56

En realidad, quería usar Tipo en mi modelo, y ya había inicializado las propiedades con un convertidor:

modelBuilder.Entity<...>()
    .Property(x => x.Type)
    .IsRequired()
    .HasConversion(
        convertToProviderExpression: x => x.AssemblyQualifiedName,
        convertFromProviderExpression: x => Type.GetType(x));

Asumí que esto habría sido suficiente para que Entity Framework Core se diera cuenta de que Type no es una entidad, pero terminé teniendo que ignorarlo explícitamente para que esto funcione:

modelBuilder.Ignore<Type>();
4
Vivelin 4 abr. 2019 a las 14:45