El tipo de entidad <tipo> no es parte del modelo para el contexto actual

147

Estoy entrando en el Entity Framework, pero no estoy seguro de si me falta un punto crítico en el enfoque de código primero.

Estoy usando un patrón de repositorio genérico basado en el código de https://genericunitofworkandrepositories.codeplex.com/ y he creado mis entidades.

Pero cuando intento acceder o modificar la entidad, me encuentro con lo siguiente:

System.InvalidOperationException: el tipo de entidad Estate no es parte del modelo para el contexto actual.

Ocurre cuando intento acceder desde mi repositorio:

public virtual void Insert(TEntity entity)
{
    ((IObjectState)entity).ObjectState = ObjectState.Added;
    _dbSet.Attach(entity); // <-- The error occurs here
    _context.SyncObjectState(entity);
}

La base de datos (./SQLEXPRESS) se crea muy bien, pero las entidades (tablas) simplemente no se crean al inicio.

Me pregunto si necesito establecer explícitamente la asignación de las entidades. ¿EF no puede hacerlo por sí solo?

Mi entidad es:

public class Estate : EntityBase
{
    public int EstateId { get; set; }
    public string Name { get; set; }
} 

Mi contexto es así:

public partial class DimensionWebDbContext : DbContextBase // DbContextBase inherits DbContext
{
    public DimensionWebDbContext() :
        base("DimensionWebContext")
    {
        Database.SetInitializer<DimensionWebDbContext>(new CreateDatabaseIfNotExists<DimensionWebDbContext>());
        Configuration.ProxyCreationEnabled = false;
    }

    public new IDbSet<T> Set<T>() where T : class
    {
        return base.Set<T>();
    }

}

¿Hay alguna razón específica por la que se produce este error? He intentado habilitar las migraciones y habilitar las migraciones automáticas sin ninguna ayuda tampoco.

janhartmann
fuente

Respuestas:

143

Pon esto en tu DbContextclase personalizada :

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Estate>().ToTable("Estate");
}

Si sus tablas no se crean al inicio, esta es la razón. Debe informarle al DbContext sobre ellos en la anulación del método OnModelCreating.

Puede hacer asignaciones personalizadas por entidad aquí, o separarlas en EntityTypeConfiguration<T>clases separadas .

danludwig
fuente
1
Gracias Dan, esto lo arregla. Ahora se crean las tablas. No hay otra forma, EF no puede hacer esto por sí solo. ¿No puedo simplemente anotar la entidad con [ToTable ('Estates')] o algo así?
Janhartmann
3
Creo que podría funcionar sin anular OnModelCreatingsi sus entidades están en el mismo ensamblado que el suyo DbContext. Sin embargo, nunca he usado anotaciones de datos para entidades, así que no puedo decir con certeza. Siempre puede escanear ensamblajes en su OnModelCreatingpara encontrar entidades en otros ensamblajes y registrarlos automáticamente (que es lo que hace Tripod).
danludwig
Ah, por supuesto. Gracias por la nota sobre la forma de hacerlo de Tripod, he hecho algo similar ahora, y parece funcionar bien. (también gracias a sus extensiones de reflexión en: github.com/danludwig/Layout3/blob/master/UCosmic.Domain/Api/… ). Ahora solo necesito que encuentre ensambles de referencias en lugar de buscar el ensamblaje GetType (). "var assembly = Assembly.Load (" Dimension.Web.Domain ");" no es bonito ;-)
janhartmann
O tal vez simplemente mueva mi nueva carpeta / Mapping / a mi proyecto Impl en lugar de mi Dominio.
Janhartmann
@meep o danludwig. ¿Puede decirme más sobre Trípode o compartir un enlace?
DkAngelito
73

Aparentemente, este error es muy genérico, podría tener varias razones. En mi caso, fue lo siguiente: La cadena de conexión (en Web.config) generada por el .edmxno era válida. Después de casi un día de intentarlo todo, cambié la cadena de conexión de la cadena EF a una cadena ADO.NET. Esto resolvió mi problema.

Por ejemplo, la cadena EF se ve así:

<connectionStrings> 
  <add name="BlogContext"  
    connectionString="metadata=res://*/BloggingModel.csdl| 
                               res://*/BloggingModel.ssdl| 
                               res://*/BloggingModel.msl; 
                               provider=System.Data.SqlClient 
                               provider connection string= 
                               &quot;data source=(localdb)\v11.0; 
                               initial catalog=Blogging;
                               integrated security=True; 
                               multipleactiveresultsets=True;&quot;" 
     providerName="System.Data.EntityClient" /> 
</connectionStrings>

Y la cadena ADO.NET se ve así:

<connectionStrings>
  <add name="BlogContext"  
        providerName="System.Data.SqlClient"  
        connectionString="Server=.\SQLEXPRESS;Database=Blogging;
        Integrated Security=True;"/> 
</connectionStrings>

Fuente: http://msdn.microsoft.com/nl-nl/data/jj556606.aspx

Christiaan Maks
fuente
17
Mi problema también estaba en la cadena de conexión. Cambié el nombre de mi modelo de datos y volví a clasificar mis plantillas t4, pero olvidé actualizar los metadatos (archivos .csdl, .ssdl, .msl) en la cadena de conexión. Su respuesta me ayudó a darme cuenta de esto, ¡así que gracias!
Vyskol
44
Si utiliza el modelo de identidad para la autenticación, necesita 2 cadenas de conexiones: una, la "Conexión predeterminada", a la que puede cambiar el nombre o no y ponerla en su ApplicationDbContext (): base ("IdentityDbContext", throwIfV1Schema: false) {} Eso es lo que provocó mi error como el tuyo (tenía la cadena EF allí). La segunda cadena de conexión es la que se hace al agregar EF usando el asistente y solicita los parámetros de la cadena de conexión. Espero que esto ayude a alguien.
JustJohn
igual que aquí. increíblemente frustrante
Nick Molyneux
1
Actualizo de EF 4.xa EF 6. Tuve que regenerar la cadena de conexión para agregar una tabla ( DatabaseFirst). No me di cuenta de que mis conexiones en el app.configy el web.configeran diferentes. Una vez que me hice cargo connectionstringdel app.config, comenzó a funcionar.
DHFW
16

Para mí, el problema era que no había incluido la clase de entidad dentro de mi conjunto de bases de datos dentro del contexto del marco de la entidad.

public DbSet<ModelName> ModelName { get; set; }
Demodave
fuente
12

Puede intentar eliminar la tabla del modelo y agregarla nuevamente. Puede hacerlo visualmente abriendo el archivo .edmx desde el Explorador de soluciones.

Pasos:

  1. Haga doble clic en el archivo .edmx desde el Explorador de soluciones
  2. Haga clic derecho en el encabezado de la tabla que desea eliminar y seleccione "Eliminar del modelo"
  3. Ahora, nuevamente haga clic derecho en el área de trabajo y seleccione "Actualizar modelo desde la base de datos ..."
  4. Agregue la tabla nuevamente desde la lista de tablas
  5. Limpia y construye la solución
Arun
fuente
8
No hay .edmx en EF Code primero.
Tuukka Haapaniemi
Sin embargo, le di un +1, porque él (u otra persona con este problema) podría querer repensar hacer Code First y hacerlo de esta manera, en su lugar :)
vapcguy
9

El problema puede estar en la cadena de conexión. Asegúrese de que su cadena de conexión sea para el proveedor SqlClient, sin elementos de metadatos relacionados con EntityFramework.

Shawn de Wet
fuente
Esto probablemente fue obvio para muchos, pero esto terminó siendo mi problema (con respecto a mezclar db-first con code-first). Ahora puedo dejar de girar mis ruedas, ¡muchas gracias!
Bonez024
3

He visto este error cuando una tabla existente en la base de datos no se asigna adecuadamente a un primer modelo de código. Específicamente tuve un char (1) en la tabla de la base de datos y un char en C #. Cambiar el modelo a una cadena resolvió el problema.

Daniel Leach
fuente
3

Mi problema se resolvió actualizando la parte de metadatos de la cadena de conexión. Aparentemente apuntaba a la referencia incorrecta .csdl / .ssdl / .msl.

ragnarswanson
fuente
Esto me pasó a mí también. Copié la cadena de conexión EF de otro lugar y no actualicé el nombre del modelo en los metadatos.
devC
2

Otra cosa para verificar con su cadena de conexión: el nombre del modelo. Estaba usando dos modelos de entidad, DB primero. En la configuración, copié la conexión de la entidad para una, la renombré y cambié la parte de la cadena de conexión. Lo que no cambié fue el nombre del modelo, por lo tanto, si bien el modelo de entidad se generó correctamente, cuando se inició el contexto, EF estaba buscando en el modelo incorrecto las entidades.

Parece obvio escrito, pero hay cuatro horas que no volveré.

Eddie
fuente
2

Para mí, el problema fue que usé el connection stringgenerado por ADO.NetModel (.edmx). Cambiar la cadena de conexión resolvió mi problema.

FN90
fuente
1

Esto también puede ocurrir si está utilizando un caché de modelo persistente que está desactualizado por una razón u otra. Si su contexto se ha almacenado en caché en un archivo EDMX en un sistema de archivos (a través de DbConfiguration.SetModelStore), nunca se llamará a OnModelCreating ya que se usará la versión en caché. Como resultado, si falta una entidad en su tienda en caché, obtendrá el error anterior a pesar de que la cadena de conexión es correcta, la tabla existe en la base de datos y la entidad está configurada correctamente en su DbContext.

strickt01
fuente
1

El mensaje era bastante claro pero al principio no lo entendí ...

Estoy trabajando con dos contextos de Entity Framework DB sysContexty shardContexten el mismo método.

La entidad que había modificado \ actualizado es de un contexto, pero luego intenté guardarlo en el otro contexto de esta manera:

invite.uid = user.uid;

sysContext.Entry(invite).State = EntityState.Modified;

sysContext.SaveChanges(); // Got the exception here

pero la versión correcta debería ser esta:

invite.uid = user.uid;

shardContext.Entry(invite).State = EntityState.Modified;

shardContext.SaveChanges();

Después de pasar la entidad al contexto correcto, este error desapareció.

Leniel Maccaferri
fuente
0

Suena obvio, pero asegúrese de no ignorar explícitamente el tipo:

modelBuilder.Ignore<MyType>();

emraginas
fuente
0

El mapa de la entidad (incluso uno vacío) agregado a la configuración conducirá a que el tipo de entidad sea parte del contexto. Teníamos una entidad sin relación con otras entidades que se solucionó con un mapa vacío.

Mcfea
fuente
0

si está probando DB primero, asegúrese de que su tabla tenga clave primaria

Mahmoud
fuente
0

Visual Studio 2019 parece causarme esto. Lo arreglé generando el modelo edmx nuevamente en 2017.

Chinupson
fuente
0

Tengo el mismo problema en Entity Framewrok y lo resolví siguiendo estos pasos:

1-Abra su Model.edmx 2-cambie un lugar de la tabla (para hacer cambios en el archivo cs) 3-guárdelo

Espero ayudarte

Akbar Asghari
fuente
0

Elimine el archivo .edmx y agréguelo nuevamente. Especialmente, si ha actualizado el Entity Framework.

Roy Oliver
fuente
0

Estaba enfrentando el mismo problema con EntityFrameworkCore tratando de actualizar un rango de valores.

Este enfoque no funcionó

  _dbSet.AttachRange(entity);
  _context.Entry(entity).State = EntityState.Modified;
   await _context.SaveChangesAsync().ConfigureAwait(false);

Después de agregar el método UpdateRange y eliminar adjuntar y entrar todo funciona

  _dbSet.UpdateRange(entity);
  await _context.SaveChangesAsync().ConfigureAwait(false);
Okyam
fuente
0

Para mí fue causado porque cambié el nombre de la clase de entidad. Cuando lo revertí, estaba bien.

Iván Kollár
fuente
0

Podría ser estúpido, pero si solo obtuvo este error en alguna Tabla, no olvide limpiar su proyecto y reconstruirlo (podría ahorrarle mucho tiempo)

LeBigCat
fuente
0

Tuve esto

using (var context = new ATImporterContext(DBConnection))
{
    if (GetID(entity).Equals(0))
    {
        context.Set<T>().Add(entity);
    }
    else
    {
        int val = GetID(entity);
        var entry = GetEntryAsync(context, GetID(entity)).ConfigureAwait(false);
        context.Entry(entry).CurrentValues.SetValues(entity);

    }
    
    await context.SaveChangesAsync().ConfigureAwait(false);
}

Esto estaba en un método asíncrono, pero me olvidé de esperar antes de GetEntryAsync, y obtuve el mismo error ...

bifedefrango
fuente