5

Je veux créer une nouvelle ligne dans ma base de données sur une table qui a quelques relations de clés étrangères et je n'ai pas pu me faire une idée sur quel ordre et quels appels doivent être faits. Voilà ce que j'ai jusqu'à présent:Comment créer des relations de clé étrangère avec Entity Framework?

db.Models.Order order = DB.Models.Order.CreateOrder(apple); 
order.CustomerReference.Attach((from c in db.Customer where c.Id == custId select c).First()); 
db.SaveChanges(); 

Le code échoue sur la deuxième ligne là, en disant:

ATTACH n'est pas une opération valide lorsque l'objet source associé à cette fin liée est dans un état ajouté ou supprimé, ou détaché. Les objets chargés à l'aide de l'option de fusion NoTracking sont toujours toujours détachés.

Des idées?

Répondre

8

(Merci John pour les corrections de grammaire)

Je compris. Voici ce que vous devez faire:

db.Models.Order order = DB.Models.Order.CreateOrder(apple); 
order.Customer = (from c in db.Customer where c.Id == custId select c).First(); 
db.SaveChanges(); 

J'espère que cela aide les gens.

6

Pourquoi ne pas utiliser des références entité? Votre méthode provoquera une instruction supplémentaire SELECT.

Une façon beaucoup plus agréable est d'utiliser la classe CustomerReference et un EntityKey.

order.CustomerReference = new System.Data.Objects.DataClasses.EntityReference<Customers>(); 
order.CustomerReference.EntityKey = new EntityKey("ModelsEntities.Customers", "Id", custId); 
+1

Je ne me dérangerait pas d'utiliser votre solution, mais je voudrais utiliser les noms de colonnes de base de données fortement typées afin que je puisse obtenir des erreurs à la compilation si la relation est invalide. – Jared

+0

Je suis d'accord avec kirkmcpherson, son chemin évite de faire le SELECT supplémentaire. Je suppose que vous appréciez le code maintenable sur les performances. Vous pouvez toujours utiliser son chemin, mais au lieu de chaînes codées en dur, vous pouvez utiliser la réflexion pour générer les chaînes en obtenant les noms de classe pour ModelsEntities et les clients dans l'exemple ci-dessus. De cette façon, vous obtenez à la fois un SELECT de moins, et de fortes erreurs de frappe/temps de compilation. Le surcoût ajouté de la réflexion ne devrait pas être un problème OMI. – jamiebarrow

+0

Bon, vous pouvez utiliser la réflexion pour générer le nom de l'ensemble d'entités, mais pas le nom de la clé (c.-à-d. Générer «ModelsEntities.Customers» en utilisant une saisie forte). Y a-t-il un moyen de générer le "Id" en utilisant la réflexion? – jamiebarrow

0

Pour la mise à jour ici est un exemple de code:

using (var ctx = new DataModelEntities()) 
{ 

     var result = (from p in ctx.UserRole.Where(o => o.UserRoleId == userRole.UserRoleId) 
           select p).First(); 

     result.RolesReference.EntityKey = new EntityKey("DataModelEntities.Roles", 
             "RoleId", userRole.RoleId); 

     result.UserRoleDescription = userRole.UserRoleDescription;  
     ctx.SaveChanges(); 
} 
Questions connexes