Primero el código de Entity Framework: no se puede insertar una clave duplicada en el objeto 'dbo.T_CRProviders'

StackOverflow https://stackoverflow.com//questions/9664378

Pregunta

Tengo un problema urgente para el cual no pude encontrar respuesta en la web.

Estoy usando CodeFirst EF 4.3.1 y aparece un error:Violation of PRIMARY KEY constraint 'PK_T_CRProviders'. Cannot insert duplicate key in object 'dbo.T_CRProviders'.

Mi código es:

Modelos:

public enum CRProviderEnums
{
    PE_Abcd = 0,
    PE_Efgh
}

[Table("T_CRProviders")]
public class CRProvider
{
    [Key]
    [Required]
    public int Enum { get; set; }
    [Required]
    public string Name { get; set; }
}

[Table("T_CRSupportedResources")]
public class CRSupportedResource
{
    [Key]
    public Guid SupportedResourceId { get; set; }
    [Required]
    public CRProvider Provider { get; set; }
}

ContextoDb:

public class RSContext : DbContext
{
    public DbSet<CRProvider> CRProviders { get; set; }
    public DbSet<CRSupportedResource> CRSupportedResources { get; set; }
}

La tabla T_CRProviders tiene este aspecto: Enum (PK), Name

La tabla T_CRSupportedResources se ve así: SupportedResourceId (PK), Provider_Enum (FK).

En la tabla de la base de datos T_CRProviders ya tengo un proveedor con los siguientes valores:

Enum: 0 (which is PE_Abcd)
Name: "PE_Abcd"

Ahora mi main() llama a un método AddSupportedResource.Este método agrega a la tabla T_CRSupportedResources un nuevo CRSupportedResource que hace referencia al proveedor 0 (PE_Abcd).El método se ve así:

public void AddSupportedResource()
    {
        CRSupportedResource supportedResource = new CRSupportedResource()
        {
            SupportedResourceId = Guid.NewGuid(),
            Provider = new CRProvider()
            {
                Enum = (int)CRProviderEnums.PE_Abcd,
                Name = "PE_Abcd"
            }
        };

        using (RSContext myContext = new RSContext())
        {
            myContext.CRSupportedResources.Add(supportedResource);

            myContext.SaveChanges();
        }
    }

Espero que este método deje la tabla T_CRProviders intacta y agregue una nueva fila a la tabla T_CRSupportedResources que se verá así:

SupportedResourceId: DE532083-68CF-484A-8D2B-606BC238AB61
Provider_Enum (FK): 0 (which is PE_Abcd).

En cambio, al realizar SaveChanges, Entity framework también intenta agregar el Proveedor a la tabla T_CRProviders y, dado que dicho proveedor ya existe, genera la siguiente excepción:

An error occurred while updating the entries.

Violation of PRIMARY KEY constraint 'PK_T_CRProviders'. Cannot insert duplicate key in object 'dbo.T_CRProviders'.

The statement has been terminated.

Mi pregunta:

¿Cómo puedo indicarle al EF que no actualice la tabla? T_CRProviders al actualizar la tabla T_CRSupportedResources?

Por cierto, en SQL Server veo esa tabla. T_CRSupportedResources tiene una clave externa llamada FK_RW_TCRSupportedCloudResources_RW_TCRCloudProviders_Provider_Enum y su regla de actualización tiene el valor de No Action.

¿Fue útil?

Solución 2

En realidad, hay una manera de hacer esto.

Vea la respuesta a mi pregunta en el siguiente enlace:

http://social.msdn.microsoft.com/Forums/en-US/adodotnetentityframework/thread/62f3e5bc-c972-4622-b830-e7d7fe710101

Otros consejos

Espero que este método deje la tabla t_crproviders intacta y agregue una nueva fila a la tabla t_crsupportedresources

No, no sucederá.Está creando un gráfico de entidad independiente que consta de una entidad existente y una entidad nueva.EF no sabe acerca de la existencia de su entidad hasta que usted le informa al respecto; no hay consultas de base de datos que validen la existencia realizadas por EF detrás.

si llamas Add método, todas las entidades en su gráfico de entidades se agregan como nuevas.Si no desea insertarlos todos, puede comenzar usando Attach y cambiar manualmente el estado de otros nuevos.Por ejemplo como:

myContext.CRSupportedResources.Attach(supportedResource);
myContext.Entry(supportedResource).State = EntityState.Added;
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top