Linq to Entité Rejoindre et de Groupe Par
Je suis nouveau sur Linq to Entité et voici mon scénario de test:
- Il y a des Utilisateurs
- Les utilisateurs ont des Albums Photo. Un album appartient qu'à un seul Utilisateur
- Albums Photos. Une Photo appartient à un seul Album
- Photos ont des Étiquettes. Une Balise peut appartenir à plusieurs Photos
Je veux écrire une méthode qui affiche le Comte et le Nom des Balises utilisées dans les Albums d'un Utilisateur à l'aide de Linq.
Voici la méthode que j'ai écrit et il fonctionne très bien
public static void TestStatistics(int userId)
{
//select AlbumTitle, TagName, TagCount where UserId = userId
var results = from photo in dbSet.PhotoSet
join album in dbSet.AlbumSet on photo.AlbumId equals album.Id into albumSet
from alb in albumSet
where alb.UserId == userId
join photoTag in dbSet.PhotoTagSet on photo.Id equals photoTag.PhotoId into photoTagSet
from pt in photoTagSet
join tag in dbSet.TagSet on pt.TagId equals tag.Id
group new { alb, tag } by new { alb.Title, tag.Name }
into resultSet
orderby resultSet.Key.Name
select new
{
AlbumTitle = resultSet.Key.Title,
TagName = resultSet.Key.Name,
TagCount = resultSet.Count()
};
foreach (var item in results)
{
Console.WriteLine(item.AlbumTitle + "\t" + item.TagName + "\t" + item.TagCount);
}
}
Et c'est le standart requête T-SQL qui fait la même
SELECT a.Title AS AlbumTitle, t.Name AS TagName , COUNT(t.Name) AS TagCount
FROM TblPhoto p, TblAlbum a, TblTag t, TblPhotoTag pt
WHERE p.Id = pt.PhotoId AND t.Id = pt.TagId AND p.AlbumId = a.Id AND a.UserId = 1
GROUP BY a.Title, t.Name
ORDER BY t.Name
Il est assez évident que la norme requête T-SQL est beaucoup plus simple que la requête Linq.
Je sais Linq n'est pas censé être plus simple que de T-SQL, mais cette complexité différence me fait penser que je suis en train de faire quelque chose de terriblement mal. En plus de la requête SQL générée par Linq est extrêmement complexe.
Est-il possible de faire la requête Linq plus simple?
Mise à JOUR 1:
Je l'ai faite un peu plus simple sans l'aide de jointures, mais en utilisant une approche comme celle utilisée en T-SQL. En fait, il est maintenant aussi simple que de T-SQL. Toujours pas de propriétés de navigation et pas de relations sur db.
var results = from photo in dbSet.PhotoSet
from album in dbSet.AlbumSet
from photoTag in dbSet.PhotoTagSet
from tag in dbSet.TagSet
where photo.AlbumId == album.Id && photo.Id == photoTag.PhotoId &&
tag.Id == photoTag.TagId && album.UserId == userId
group new { album, tag } by new { album.Title, tag.Name } into resultSet
orderby resultSet.Key.Name
select new {
AlbumTitle = resultSet.Key.Title,
TagName = resultSet.Key.Name,
TagCount = resultSet.Count()
};
OriginalL'auteur Mehmet Ataş | 2012-11-06
Vous devez vous connecter pour publier un commentaire.
Si chaque photo a au moins une balise , puis essayez
OriginalL'auteur sgmoore
Tout d'abord, vous devez configurer les clés étrangères dans votre base de données puis de reconstruire les objectifs EF et il "savoir" (c'est à dire les propriétés de navigation) sur les relations, qui permet d'omettre tous vos jointures et d'utiliser quelque chose le long des lignes suivantes:
ps.PhotoTag
est collection, donc je ne peux pas utiliser.Tag
après. Si j'utiliseFirstOrDefault
code s'exécute, mais donne un résultat incorrectOriginalL'auteur Paul Zahra