2013-02-08 3 views
0

J'ai un problème avec l'implémentation d'une vérification qui empêche un développeur de mettre à jour manuellement ou par programme la clé primaire dans le code après la création initiale.Entity Framework OnChanging protège les clés primaires

partial class User 
{ 
    public User() 
    { 
     this.UserId = sGuid.NewSGuid(sGuidType.SequentialAtEnd); 
    } 

    partial void OnUserIdChanging(Guid value) 
    { 
     //throw if its an edit... 
     throw new DbEntityValidationException("Cannot mutate primary key"); 
    } 

} 

Cela fonctionne bien si je suis d'édition/mise à jour d'un objet, mais il ne me laisse pas réellement créer une nouvelle entité en premier lieu. Y a-t-il un moyen que je puisse vérifier à ce stade pour voir s'il s'agit d'une nouvelle entité ou d'une entité existante?

Merci à l'avance, Pete

MISE À JOUR:

typique Je trouve toujours la réponse après que je poste -_-! Merci pour votre réponse gars, je vais marquer l'un des vôtres comme une réponse correcte car ils étaient des alternatives valables.

if (this.EntityState != System.Data.EntityState.Detached) 
{ 
    throw new DbEntityValidationException("Cannot mutate primary key"); 
} 
+0

Eh bien, vous pouvez interroger la base de données avec la clé, si c'est là une édition, sinon, c'est un nouvel objet ... ou je reçois quelque chose de mal? –

+0

Pourquoi ne pas simplement rendre votre accesseur UserId privé? –

+0

J'ai pensé à cela (en le réglant à privé) qui fonctionne. Mais cela ne les empêche pas de générer des méthodes de classe qui peuvent le mettre à jour. Mais je suppose que cela ne les empêchera peut-être pas de supprimer complètement le chèque. Lors de l'événement onChanging, vous obtenez simplement la nouvelle valeur et si elle a été définie manuellement, vous risquez d'obtenir une collision avec le mauvais enregistrement. La raison pour laquelle je veux éviter de la rendre privée est que j'ai utilisé la génération automatique de code et il est détruit chaque fois que je mets à jour le modèle>< –

Répondre

1

Ce problème est généralement résolu en faisant setters clé primaire private ou protected:

public class MyEntity 
{ 
    public int Id { get; private set; } 
} 

Si vous utilisez concepteur EF, juste la propriété de sélection dans le concepteur et définir le modificateur d'accès approprié dans la grille de la propriété - Votre générateur de code fera le reste.

+0

Salut, voir mon commentaire ci-dessus, je suppose que je le voulais à l'événement onChanging pour supprimer la possibilité de mettre à jour les méthodes internes des classes et de faire quelque chose de stupide. Mais s'il n'y a pas moyen de contourner cela je suppose que je n'ai pas le choix :( –

+0

@PeterLea Vous devriez vous concentrer plus sur avertir le développeur qu'ils font quelque chose de mal (si le fait qu'ils doivent modifier une méthode interne isn Je ne vous en dirai pas assez, rien n'est) que d'essayer d'éliminer complètement la stupidité, je vous le promets, cette dernière est une tâche impossible. – Dan

Questions connexes