Question

Cela semble que cela devrait être tout à fait évident, mais quelque chose sur le cadre de l'entité me confondre et je ne peux pas obtenir ce travail.

Tout simplement, j'ai trois tables où les valeurs d'identification sont des colonnes d'identité: Les utilisateurs (userId, nom d'utilisateur) Catégories (categoryId, categoryName) JoinTable (UserId, CategoryId) composite.

Dans les entités designer (c'est .net 4.0), quand j'importer ces tables, comme prévu la table de jointure ne semble pas, mais les utilisateurs et les catégories montrent une relation. Le code suivant:

var _context = new MyContext();
var myUser = new User();
myUser.UserName = "joe";

var myCategory = new Category();
myCategory.CategoryName = "friends";

_context.Users.AddObject(myUser);  
myUser.Categories.Add(myCategory);

var saved = _context.SaveChanges();

Renvoie une erreur de (bien que rien n'a été ajouté à la base de données):

An item with the same key has already been added.

Si j'ajoute ce qui suit avant d'enregistrer:

_context.Categories.AddObject(myCategory);
myCategory.Users.Add(myUser);

Je reçois la même erreur et rien enregistré sur le db. Si je sauve le myUser et l'objet myCategory avant d'essayer de les associer, ils ont tous deux sauver, mais le second sauvegarde jette une erreur, rien ajouté à la table de jointure:

Cannot insert the value NULL into column 'UserId', table '...dbo.JoinTable'; column does not  allow nulls. INSERT fails. The statement has been terminated.

Je suis bien ne pas comprendre combien sont insérés à de nombreuses relations. Qu'est-ce que je manque?

Était-ce utile?

La solution

Vous avez besoin d'appeler SaveChanges () après avoir ajouté des entités et de catégorie utilisateur à la base de données, puis définissez votre association entre eux.

Cependant, le vrai problème est ici la deuxième exception que vous avez énumérés. Si vous regardez SQLProfiler ou le profileur de ADO.NET dans le débogueur, vous verrez que pendant la deuxième SaveChanges appeler ressemble à quelque chose comme ceci:

insert [dbo].[JoinTable]([UserId]) values (@0) select [CategoryId] from
[dbo].[JoinTable] where @@ROWCOUNT > 0 and [UserId] = @0 and [CategoryId] = scope_identity()

Il est évident que cela ne fonctionnera pas si vous programmez votre joinTable correctement (composite PK sur les deux colonnes).

Si je regarde le magasin EntityModel via le navigateur de modèle, il montre que la colonne CategoryId à l'intérieur joinTable a en effet StoreGeneratedPattern mis à l'identité tout en UserId est défini sur Aucun. Pourquoi EF a fait cela au cours de la phase de génération lorsqu'un composite PK était présent est au-delà de moi. Je vais poster un bug à ce sujet à MS, mais dans le même temps, vous pouvez modifier manuellement le fichier edmx / SSDL après génération pour enlever le prescripteur d'identité. Trouvez la StoreGeneratedPattern = chaîne « d'identité » sous l'étiquette de propriété de la balise EntityType pour votre joinTable et retirez-le:

Changement:

<Property Name="CategoryId" Type="int" Nullable="false" StoreGeneratedPattern="Identity" />

Pour:

<Property Name="CategoryId" Type="int" Nullable="false" />

Ensuite, lorsque vous exécutez votre code, vous obtiendrez une requête d'insertion beaucoup mieux (et non plus exception!):

insert [dbo].[JoinTable]([UserId], [CategoryId]) values (@0, @1)

Autres conseils

La façon dont je l'ai fait est d'abord générer une entité de catégorie valide avec la clé de l'entité.

Category myCategory = _context.Categories.First(i => i.CategoryID == categoryIDToUse);

Vous pouvez essayer de créer l'entité comme un talon pour sauver le coup à la DB:

Category myCategory = new Category{CategoryID = categoryIDToUse };

Ensuite, ajoutez cette entité à l'ensemble des entités (CategorySet) sur la ObjectContext selon la méthode de AttachTo (vous pouvez vérifier si elle est déjà attaché). Ensuite, vous pouvez ajouter la catégorie à votre entité utilisateur à l'aide de la méthode Add. Quelque chose comme ceci:

myUser.Categories.Add(myCategory);

Appel SaveChanges (). Cela a fonctionné pour moi.

Lorsque le nouveau parent ajouté au contexte, l'état de tous les objets dans les changements d'arbres objet à Ajout et donc EF essaie de sauver tous ces objets comme nouveau record.

Reportez-vous ce lien: http://nileshhirapra.blogspot.in/2012/03 /entity-framework-insert-operation-with.html

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top