我是 Linq to Entity 的新手,这是我的测试场景:
- 有用户
- 用户有相册。一张专辑只属于一个用户
- 相册有照片。一张照片只属于一个相册
- 照片有标签。一个标签可能属于许多照片
我想编写一个方法来显示使用 Linq 的特定用户的相册中使用的标签的计数和名称。
这是我写的方法,效果很好
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);
}
}
这是执行相同操作的标准 T-SQL 查询
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
很明显,标准 T-SQL 查询比 Linq 查询简单得多。我知道 Linq 不应该比 T-SQL 更简单,但是这种复杂性差异让我觉得我做错了什么。此外,Linq 生成的 SQL 查询极其复杂。
有什么方法可以让 Linq 查询更简单?
更新 1:
我没有使用连接,而是使用了 T-SQL 中使用的方法,使它变得更简单一些。实际上它现在就像 T-SQL 一样简单。数据库上仍然没有导航属性,也没有关系。
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()
};