Ecriture d'un CTE récursif à l'aide de la syntaxe Entity Framework Fluent ou de la syntaxe Inline
Je suis nouveau sur ce la récursivité en SQL et Entity Framework (ADO.NET la projection d'Entité). Je suis en train de travailler sur un commentaire de gestion où j'ai un Comments
de la table et de la table contient des colonnes NewsID, CommentID, ParentCommentID, IndentLevel, CreatedTime
.
Je suis en train d'essayer d'obtenir une liste de commentaires pour un article particulier où tous les commentaires sont organisés en fonction de l'enfant de moins de parent et créé le temps, comme indiqué ci-dessous:
CommentID | time | ParentCommentID
Guid1 | t1 | null
Guid4 | t4 | Guid1
Guid2 | t2 | null
Guid3 | t3 | Guid2
La priorité doit être donnée à l'enfant de la relation parent, puis la date de création.
Ce que j'ai penché la mesure est (à partir de ressources de l'internet et de la précédente stackoverflow Q/A)
- Comme l'illustrent ces requêtes récursives sont lents. et ce faisant à l'aide de Entity Framework est encore plus lente. Mais il peut être accompli.
- Donc, Il peut être fait par la création d'une procédure stockée dans SQL Server et l'appel à l'aide d'une fonctionnelle d'importation. Une autre chose est l'utilisation de Linq dans le Cadre de l'Entité.
- Dans SQL Server, il est utilisé dans ce format
SQL:
WITH cte_name ( column_name [,...n] )
AS
(
CTE_query_definition –- Anchor member is defined.
UNION ALL
CTE_query_definition –- Recursive member is defined referencing cte_name.
)
-- Statement using the CTE
SELECT *
FROM cte_name
- Mais avant de tenter cela, je veux essayer le Linq.
Pour cela, j'ai fait référence à ce lien où j'ai eu l'idée:
https://stackoverflow.com/a/6225373/892788
Mais j'ai essayé de comprendre le code, mais en vain. Quelqu'un peut-il me donner une meilleure explication détaillée sur la rédaction d'expression de table commune récursive dans l'Entity Framework?
private IEnumerable<NewsComment> ArrangeComments(IEnumerable<NewsComment> commentsList, string parentNewsComntID, int level)
{
Guid parentNewsCommentID;
if (parentNewsComntID != null)
{
parentNewsCommentID = new Guid(parentNewsComntID);
}
else
parentNewsCommentID = Guid.Empty;
return commentsList.Where(x => x.ParentCommentID == parentNewsCommentID).SelectMany(x => new[] { x }.Concat(ArrangeComments(commentsList, x.NewsCommentID.ToString(), level + 1));
}
Et je me sers de ce que ci-dessous à l'intérieur d'une méthode:
return ArrangeComments(commentList,null , 0);
J'ai essayé et il semble que je suis nulle part. Si il y a des explications sur le SQL de la récursivité il y a moins d'exemples de Linq et sont vague pour moi en raison de moins de familiarité. Quelqu'un peut-il m'aider à comprendre ce CTE récursivité dans Linq qui est de grande
Merci d'avance
source d'informationauteur Diyoda_
Vous devez vous connecter pour publier un commentaire.
Autant que je sache, il n'y a pas de support pour les expressions cte dans LINQ, ni dans les EF. La solution est d'exposer la CTE comme un point de vue. L'article sur Récursive ou des requêtes hiérarchiques à l'aide de EF Premier Code et les Migrations montre comment déployer un tel point de vue à l'aide de EF premier code migrations.
Tentant de reproduire les expressions de table communes en faisant récursive côté client itérations n'est pas à l'échelle de grands ensembles de données et les résultats dans un moulin à paroles échange avec le serveur. Remarquez comment votre EF code renvoie
IEnumerable
pasIQueryable
cela signifie qu'il se matérialise chaque niveau, puis concatène le prochain niveau pour chaque entrée comme une demande distincte. Le LINQ base de la solution raisonnable pour les hiérarchies limite d'inscription le comte (et notez que de nombreux projets peut ont une telle disposition de données, de messages de l'utilisateur/réponses étant un exemple typique), mais s'écroulera sous les hiérarchies profondes avec de nombreux éléments.Mettre la CTE de la requête à la StoredProcedure, et ensuite appeler à partir du Code. EF fournit tous les moyen pour le faire (l'appel de la SP et de la récupération des résultats). J'ai fait de même pour moi, fonctionne très bien.
Écrit CTE Requête Linq n'est PAS possible
Expression de Table commune (CTE) de linq-to-sql?
L'Échantillon ArrangeComments est une procédure récursive qui s'appeler lui-même, mais je n'ose remettre en question la performance. Il tire les enregistrements à partir de DB, puis applique des opérations en mémoire.
Après avoir passé plusieurs heures à lire à propos de ce problème j'ai décidé de le faire en C# et ne pas avoir à créer une vue de base de données.
REMARQUE: à Utiliser seulement pour les non critique pour les performances de l'opération. Exemple avec 1000 nœuds de la performance de http://nosalan.blogspot.se/2012/09/hierarchical-data-and-entity-framework-4.html.
Code: