2010-09-01 3 views
2

Je travaille sur une application distribuée avec un serveur et un client, où le serveur expose des services via WCF. Le serveur utilise Entity Framework et ses diverses méthodes retournent EntityObjects.Problème avec FK dans EF après l'aller-retour WCF

Dans le client, je n'ai aucune référence au serveur. Ainsi, dans le client, les classes sont des proxies entièrement générés.

J'ai une méthode de suppression dans le serveur. Quand je passe un objet (retour) à elle pour la suppression, il le fait (dépouillé de la gestion des exceptions, etc.):

public void DeleteCarrier(CarrierDefinition carrier) 
{ 
    var container = new WsaEntities(); 

    if (carrier.EntityState == EntityState.Detached) 
    { 
     container.CarrierDefinitions.Attach(carrier); 
    } 
    container.CarrierDefinitions.DeleteObject(carrier); 

    container.SaveChanges(); 
} 

Deux autres tables ont des clés étrangères à CarrierDefinition. Un des FK est nullable avec une contrainte ON CASCADE SET NULL, l'autre a CASCADE DELETE. Le code ci-dessus me lance une exception:

L'opération a échoué: La relation ne pouvait pas être changé parce que l'un ou plusieurs des propriétés de clé étrangère est non annulable. Lorsqu'une modification est apportée à une relation, la propriété de clé étrangère associée est définie sur une valeur null . Si la clé étrangère ne prend pas en charge les valeurs nulles , une nouvelle relation doit être définie, la propriété de clé étrangère doit être affectée à une autre valeur non nulle ou l'objet non lié doit être supprimé.

Cependant, si je supprime une entité qui n'a pas été de cette manière ronde trébuché, il fonctionne comme prévu:

public void DeleteCarrier(Guid carrierId) 
{ 
    var container = new WsaEntities(); 

    var c = container.CarrierDefinitions.Where(cd => cd.Id == carrierId).First(); 
    container.CarrierDefinitions.DeleteObject(c); 

    container.SaveChanges(); 
} 

Ici, le ON CASCADE SET NULL et ON CASCADE DELETE fonctionne très bien.

J'ai inspecté l'argument carrier (entity) en mode débogage, et je n'ai pas réussi à trouver quelque chose qui ne va pas. Plus précisément, les collections d'entités sont remplies et contiennent les objets associés. Il semble incroyablement complet et correct, étant donné qu'il a été sérialisé, puis désérialisé à une classe proxy et vice versa. Mais quelque part, quelque chose ne va pas tout à fait juste.

Je sais que je peux tout aussi bien utiliser cette signature de méthode et passer à autre chose, ou même conserver la signature et utiliser la propriété Id de l'argument carrier à la place de l'argument carrierId. Mais je crains que ce sera le premier de nombreux problèmes parce que quelque chose ne va pas avec toute l'approche.

Que puis-je essayer? Y a-t-il quelque chose que je devrais faire en plus d'attacher l'entité, par exemple?

Je dois mentionner que j'utilise SQL Server Compact Edition v3.5 ici, même si cela ne me semble pas être le problème dans ce cas particulier.

Répondre

0

Pour ceux d'entre vous qui pourraient être ici avec le même genre de problème: J'ai résolu ce problème en passant à self-tracking entities. Ceux-ci sont faits pour le déclenchement rond, et sont beaucoup plus faciles à travailler au retour. Vérifiez-le.