Linq to Entity Join und Group By
Ich bin neu in Linq to Entity und hier ist mein test-Szenario:
- Es gibt user
- Die Nutzer haben Foto-Alben. Ein album gehört, um nur ein Benutzer
- Alben Fotos haben. Ein Foto gehört zu nur einem Album
- Fotos haben Tags. Ein Tag gehört möglicherweise zu viele Fotos
Möchte ich schreiben, eine Methode, die zeigt Anzahl und Namen der verwendeten Tags in Alben eines bestimmten Benutzers mithilfe von Linq.
Hier ist die Methode, die ich schrieb, und es funktioniert gut
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);
}
}
- Und dies ist der standart T-SQL-Abfrage, die nicht die gleiche
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
Es ist ziemlich offensichtlich, dass standard-T-SQL-Abfrage ist viel einfacher als die Linq-Abfrage.
Ich weiß, Linq nicht, soll einfacher sein als die T-SQL, aber diese Komplexität Unterschied lässt mich denken, dass ich Tue, etwas schrecklich falsch. Neben der SQL-Abfrage generiert, die von Linq ist extrem Komplex.
Gibt es eine Möglichkeit, um die Linq-query einfacher?
UPDATE 1:
Ich machte es ein wenig einfacher, ohne die Verwendung von joins, sondern mit einem Ansatz, wie z.B. in T-SQL. Tatsächlich ist es nun so einfach wie T-SQL. Immer noch keine navigation Eigenschaften und keine Beziehungen in der 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()
};
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wenn jedes Foto hat mindestens einen tag , dann versuchen Sie
First things First, müssen Sie die setup-foreignkeys in Ihrer Datenbank dann neu erstellen, EF und es wird "wissen" (z.B. navigation Eigenschaften) über die Beziehungen, die können Sie dann weglassen, alle Ihre Verknüpfungen und verwenden Sie etwas entlang der Linien der folgenden:
ps.PhotoTag
ist die Sammlung, so kann ich nicht verwenden.Tag
danach. Wenn ichFirstOrDefault
code ausgeführt wird, aber gibt Falsches Ergebnis