J'insère un certain nombre d'instances d'un objet particulier dans une base de données à l'aide de Entity Framework. J'ai un seul contexte d'objet auquel j'attache plusieurs objets 'Product'. L'objet que j'insère n'a aucun lien avec une autre table de la base de données. C'est une entité purement autonome. J'utilise l'outil 'EFProf' pour profiler l'application. Lorsque j'appelle 'SaveChanges()' pour conserver mes entités 'Product' à SQL Server, EFProf m'avertit que j'ai l'anti-pattern 'Select N + 1'. Je ne vois pas comment cela est possible puisque j'insère simplement. Ma compréhension de 'Select N + 1' est qu'il se rapporte à la récupération d'objets inefficace. Je ne récupère rien, je l'insère seulement. Lorsque j'examine le SQL généré, je vois que Entity Framework a généré une instruction select en mon nom qui retourne l'ID de l'objet nouvellement inséré. Cette instruction select est effectuée pour chaque entité que j'insère. Est-ce que ceci pourrait être la cause du problème choisi de N + 1? Si oui, comment puis-je éviter cet anti-pattern lors de l'insertion d'un certain nombre d'entités du même type dans un seul appel à SaveChanges()?Entités d'encombrement Entity Framework entraînant un problème n + 1 de sélection
Le SQL généré est ci-dessous:
insert [dbo].[Products]
([ProductName],
[ProductNum],
[Price],
[EntryDate],
[Description],
[Category],
[UnitsInStock])
values('TestProduct' /* @0 */,
0 /* @1 */,
0 /* @2 */,
'2011-07-09T17:14:49.00' /* @3 */,
'Category: Test Products - Name TestProduct' /* @4 */,
'Test Products' /* @5 */,
0 /* @6 */)
select [Id]
from [dbo].[Products]
where @@ROWCOUNT > 0
and [Id] = scope_identity()
C'est un commentaire vraiment utile merci. Je fais actuellement des tests de performance sur NHibernate et Entity Framework. C'est le premier cas de test que j'ai exécuté et mes résultats pour NHibernate sont tellement plus rapides (même sans batching) que je commence à me demander ce qui ne va pas avec mon code. J'ai mes cas de test mis en œuvre de manière identique à ce que je peux voir. Quand vous dites que les performances EF sont «terriblement mauvaises» pour les encarts en masse, sur quoi vous basez-vous?Je devrai écrire mes résultats si vous avez d'autres études ou articles décrivant ce problème qui serait extrêmement utile. Merci. – JMc
C'est facile. Supposons que vous créez un objet avec des objets connexes dans votre application. Par exemple commander avec 50 articles de commande. Si vous avez une fonctionnalité appelée "batch batch" (NHibernate l'a si elle est utilisée correctement), vous ferez un aller-retour vers la base de données et elle contentera 51 insertions (1 commande, 50 items). Si vous faites la même chose avec EF, il fera séquentiellement 51 roundtripts vers la base de données contenant chacun une insertion simple. Roundtrip est la partie la plus lente de presque toutes les opérations que vous pouvez faire. –