Entity Framework: tabla sin clave primaria


Tengo una base de datos existente con la que me gustaría crear una nueva aplicación usando EF4. 0

Algunas tablas no tienen claves primarias definidas de modo que cuando creo un nuevo Modelo de Datos de Entidad, recibo el siguiente mensaje: "La tabla/ver NOMBRE_DE_ tabla no tiene una clave primaria definida y no se puede inferir ninguna clave primaria válida. Esta tabla/vista ha sido excluida. Para usar la entidad, deberá revisar su esquema, agregar las claves correctas y descomentarlo".

Si quiero usarlos y modificar datos, ¿debo necesariamente agregar un PK a esas tablas, o hay una solución alternativa para que no tenga que hacerlo?

Author: vivek nuna, 2010-10-22

15 answers

El error significa exactamente lo que dice.

Incluso si pudieras solucionar esto, créeme, no quieres. El número de errores confusos que se podrían introducir es asombroso y aterrador, por no mencionar el hecho de que su rendimiento probablemente irá por los tubos.

No trabajes alrededor de esto. Arregla tu modelo de datos.

EDIT: He visto que varias personas están rechazando esta pregunta. Eso está bien, supongo, pero tenga en cuenta que la operación pidió acerca de la asignación de una tabla sin una clave primaria, no una vista . La respuesta sigue siendo la misma. Trabajar en torno a la necesidad de EF de tener un PK en las tablas es una mala idea desde el punto de vista de la capacidad de gestión, la integridad de los datos y el rendimiento.

Algunos han comentado que no tienen la capacidad de arreglar el modelo de datos subyacente porque están asignando a una aplicación de terceros. Eso no es una buena idea, ya que el modelo puede cambiar de debajo de usted. Podría decirse que, en ese caso, quisiera mapear a una vista, que, una vez más, no es lo que pidió la OP.

 53
Author: Dave Markle,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-03 09:18:35

Creo que esto es resuelto por Tillito:

Entity Framework y SQL Server View

Citaré su entrada a continuación:

Teníamos el mismo problema y esta es la solución:

Para forzar a entity framework a usar una columna como clave primaria, use ISNULL.

Para forzar a entity framework a no usar una columna como clave primaria, use NULLIF.

Una manera fácil de aplicar esto es envolver la instrucción select de su vista en otra seleccionar.

Ejemplo:

SELECT
  ISNULL(MyPrimaryID,-999) MyPrimaryID,
  NULLIF(AnotherProperty,'') AnotherProperty
  FROM ( ... ) AS temp

Respondida el 26 de abril del 10 a las 17: 00 por Tillito

 100
Author: Colin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:10:43

Las claves compuestas también se pueden hacer con Entity Framework Fluent API

public class MyModelConfiguration : EntityTypeConfiguration<MyModel>
{
     public MyModelConfiguration()
     {
        ToTable("MY_MODEL_TABLE");
        HasKey(x => new { x.SourceId, x.StartDate, x.EndDate, x.GmsDate });
        ...
     }
}
 10
Author: Adrian Garcia,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-18 14:42:01

En mi caso tuve que asignar una entidad a una vista, que no tenía clave primaria. Además, no se me permitió modificar esta vista. Afortunadamente, esta vista tenía una columna que era una cadena única. Mi solución fue marcar esta columna como clave principal:

[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
[StringLength(255)]
public string UserSID { get; set; }

Engañó a EF. Funcionó perfectamente, nadie se dio cuenta... :)

 5
Author: Boris Lipschitz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-02-11 01:18:46

ESTA SOLUCIÓN FUNCIONA

No necesita mapear manualmente incluso si no tiene un PK. Solo necesita decirle a EF que una de sus columnas es index y la columna index no es nullable.

Para hacer esto, puede agregar un número de fila a su vista con la función isNull como la siguiente

select 
    ISNULL(ROW_NUMBER() OVER (ORDER BY xxx), - 9999) AS id
from a

ISNULL(id, number) es el punto clave aquí porque le dice a EF que esta columna puede ser clave primaria

 5
Author: Barny,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-07-08 13:46:32

EF no requiere una clave primaria en la base de datos. Si lo hiciera, no podría vincular entidades a vistas.

Puede modificar la SSDL (y la CSDL) para especificar un campo único como clave principal. Si usted no tiene un campo único, entonces creo que está regado. Pero realmente debería tener un campo único (y un PK), de lo contrario se encontrará con problemas más adelante.

Erick

 4
Author: Erick T,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-10-22 20:20:44

Si quiero usarlos y modificar datos, ¿debo necesariamente agregar un PK a esas tablas, o hay una solución para que no tenga que hacerlo?

Para aquellos que llegan a esta pregunta y están utilizando Entity Framework Core, ya no es necesario agregar necesariamente un PK a esas tablas o hacer cualquier solución. Desde EF Core 2.1 tenemos una nueva característica Tipos de consulta

Los tipos de consulta deben usarse para:

  • Sirviendo como el tipo de retorno para ad hoc Consultas FromSql ().
  • Asignación a vistas de base de datos.
  • Asignación a tablas que no tienen definida una clave primaria.
  • Asignación a consultas definidas en el modelo.

Así que en su DbContext simplemente agregue la siguiente propiedad de tipo DbQuery<T> en lugar de DbSet<T> como a continuación. Suponiendo que el nombre de la tabla es MyTable:

public DbQuery<MyTable> MyTables { get; set; }
 3
Author: CodeNotFound,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-30 10:13:35

Las respuestas anteriores son correctas si realmente no tiene un PK.

Pero si hay uno pero simplemente no está especificado con un índice en la BD, y no puede cambiar la BD (sí, trabajo en el mundo de Dilbert), puede asignar manualmente el campo(s) para que sea la clave.

 2
Author: Poker Villain,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-10-22 14:50:51

Tener una clave de identidad inútil a veces no tiene sentido. Me parece que si el ID no se utiliza, ¿por qué agregarlo? Sin embargo, Entity no es tan indulgente al respecto, por lo que agregar un campo de ID sería lo mejor. Incluso en el caso de que no se use, es mejor que tratar con los errores incesivos de la Entidad sobre la clave de identidad faltante.

 2
Author: IyaTaisho,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-08-28 17:42:07

Esto es solo una adición a la respuesta de @Erick T. Si no hay una sola columna con valores únicos, la solución es usar una clave compuesta, de la siguiente manera:

[Key]
[Column("LAST_NAME", Order = 1)]
public string LastName { get; set; }

[Key]
[Column("FIRST_NAME", Order = 2)]
public string FirstName { get; set; }

Nuevamente, esto es solo una solución alternativa. La solución real es arreglar el modelo de datos.

 2
Author: Developer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-09-09 11:18:27
  1. Cambie la estructura de la tabla y agregue una columna Primaria. Actualizar el Modelo
  2. Modificar el .Archivo EDMX en el Editor XML e intente agregar una Nueva columna bajo etiqueta para esta tabla específica (NO FUNCIONARÁ)
  3. En lugar de crear una nueva Columna Primaria para salir de la tabla, haga una clave compuesta involucrando todas las columnas existentes (TRABAJADAS)

Entity Framework: Agregar DataTable sin Clave Primaria al Modelo de Entidad.

 1
Author: Pratap,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-08-23 14:40:37

Esto tal vez tarde para responder...obstante...

Si una tabla no tiene una clave primaria, entonces hay pocos escenarios que deben analizarse para que el EF funcione correctamente. La regla es: EF funcionará con tablas / clases con clave primaria. Así es como hace el seguimiento...

Diga, su mesa 1. Los registros son únicos: la unicidad se realiza mediante una sola columna de clave foránea: 2. Los registros son únicos: la singularidad se realiza mediante una combinación de varias columnas. 3. Los registros no son único (en su mayor parte*).

Para los escenarios #1 y #2 puede agregar la siguiente línea al módulo DbContext OnModelCreating method: modelBuilder.Entidad().HasKey(x => new { x.column_a, x.column_b }); // como tantas columnas como sea necesario para hacer registros únicos.

Para el escenario #3 aún puede usar la solución anterior (#1 + #2) después de estudiar la tabla (*lo que hace que todos los registros sean únicos de todos modos). Si debe incluir TODAS las columnas para hacer que todos los registros sean únicos, es posible que desee agregar un columna de clave primaria a su tabla. Si esta tabla es de un proveedor de terceros, clone esta tabla a su base de datos local (durante la noche o tantas veces como necesite) con la columna de clave primaria agregada arbitrariamente a través de su script de clonación.

 1
Author: Sam Saarian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-09 12:01:57

Desde un punto de vista práctico, cada mesa even incluso una mesa desnormalizada como una mesa de almacén should debe tener una clave primaria. O, en su defecto, debería tener al menos un índice único, no anulable.

Sin algún tipo de clave única, los registros duplicados pueden (y aparecerán) en la tabla, lo que es muy problemático tanto para las capas OR como para la comprensión básica de los datos. Una tabla que tiene registros duplicados es probablemente un síntoma de mal diseño.

Como mínimo, la tabla debe tener al menos una columna de identidad. Agregar una columna de ID de generación automática tarda aproximadamente 2 minutos en SQL Server y 5 minutos en Oracle. Por ese poco de esfuerzo adicional, muchos, muchos problemas serán evitados.

 0
Author: Ash8087,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-12-06 14:57:57

También encontramos este problema, y aunque teníamos una columna que tenía nulos, lo importante era que teníamos una columna dependiente que no tenía nulos y que la combinación de estas dos columnas era única.

Así que para citar la respuesta dada por Pratap Reddy, funcionó bien para nosotros.

 0
Author: Azerax,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-01-21 13:32:33

La tabla solo necesita tener una columna que no permita nulls

 -6
Author: mister9,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-12 20:52:40