Entity Framework Code First - Impossible d'insérer une clé en double dans l'objet 'dbo.T_CRProviders'

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

Question

J'ai un problème urgent auquel je n'ai pas trouvé de réponse sur le Web.

J'utilise CodeFirst EF 4.3.1 et j'obtiens une erreur :Violation of PRIMARY KEY constraint 'PK_T_CRProviders'. Cannot insert duplicate key in object 'dbo.T_CRProviders'.

Mon code est :

Des modèles:

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; }
}

Contexte de base de données :

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

Le tableau T_CRProviders ressemble à ceci : Enum (PK), Name

Le tableau T_CRSupportedResources ressemble à ceci : SupportedResourceId (PK), Provider_Enum (FK).

Dans la table de base de données T_CRProviders, j'ai déjà un fournisseur avec les valeurs suivantes :

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

Maintenant, mon main() appelle une méthode AddSupportedResource.Cette méthode ajoute à la table T_CRSupportedResources un nouveau CRSupportedResource qui fait référence au fournisseur 0 (PE_Abcd).La méthode ressemble à ceci :

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();
        }
    }

Je m'attends à ce que cette méthode laisse la table T_CRProviders intacte et ajoute une nouvelle ligne à la table T_CRSupportedResources qui ressemblera à ceci :

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

Au lieu de cela, lors de SaveChanges, Entity Framework essaie également d'ajouter un fournisseur à la table T_CRProviders, et comme un tel fournisseur existe déjà, il lève l'exception suivante :

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.

Ma question:

Comment puis-je demander à l'EF de ne pas mettre à jour la table T_CRProviders lors de la mise à jour du tableau T_CRSupportedResources?

Au fait, dans SQL Server, je vois cette table T_CRSupportedResources a une clé étrangère nommée FK_RW_TCRSupportedCloudResources_RW_TCRCloudProviders_Provider_Enum et sa règle de mise à jour a la valeur de No Action.

Était-ce utile?

La solution 2

En fait, il existe un moyen de procéder.

Voir la réponse à ma question dans le lien suivant :

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

Autres conseils

Je m'attends à ce que cette méthode quitte le tableau T_CRPROVIDERS intact et ajoutera une nouvelle ligne au tableau T_CRSUPPORTEDRESOURCES

Non, cela n'arrivera pas.Vous créez un graphique d'entité détaché composé d'une entité existante et d'une nouvelle entité.EF ne connaît pas l'existence de votre entité jusqu'à ce que vous l'en informiez - il n'y a aucune requête DB validant l'existence effectuée par EF derrière.

Si tu appelles Add méthode, toutes les entités de votre graphique d’entité sont ajoutées comme nouvelles.Si vous ne souhaitez pas tous les insérer, vous pouvez commencer par utiliser Attach et changez manuellement l'état pour les nouveaux.Par exemple comme :

myContext.CRSupportedResources.Attach(supportedResource);
myContext.Entry(supportedResource).State = EntityState.Added;
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top