想象一下作者和物品之间的多对多关系。
查询项目的作者时,似乎有两种广泛的方法(下面的例子)。
为什么我可以选择一种方法而不是另一种?
下面两个查询的SQL生成方式有什么不同吗?
接近一个
按ID查找项目,然后使用Authors属性列出作者。
List<Authors> Authors = db.Items
.Where(i => i.ID == CurrentItemID)
.FirstOrDefault()
.Authors.ToList();
接近两个
查找包含当前项目ID的AuthoredItems的所有作者。
List<Authors> Authors = db.Authors
.Where(i => i.AuthoredItems.Any(a => a.ID == CurrentItemID))
.ToList();
多对多关系如此:
public class Item
{
...
ICollection<Author> Authors {get;set;}
}
public class Author
{
...
ICollection<Item> AuthoredItems {get;set;}
}
更新
正如所建议的,我试图为这些查询打印生成的sql。
方法1给了我:
SELECT
[Project1].[ID] AS [ID], [Project1].[Title] AS [Title],
[Project1].[C1] AS [C1], [Project1].[ID1] AS [ID1],
[Project1].[Name] AS [Name]
FROM (
SELECT [Extent1].[ID] AS [ID],
[Extent1].[Title] AS [Title],
[Join1].[ID] AS [ID1],
[Join1].[Name] AS [Name],
CASE WHEN ([Join1].[Author_ID] IS NULL) THEN CAST(NULL AS int) ELSE 1 END AS [C1] FROM [dbo].[Items] AS [Extent1]
LEFT OUTER JOIN (
SELECT [Extent2].[Author_ID] AS [Author_ID],
[Extent2].[Item_ID] AS [Item_ID],
[Extent3].[ID] AS [ID], [Extent3].[Name] AS [Name]
ROM [dbo].[AuthoredItems] AS [Extent2]
INNER JOIN [dbo].[Authors] AS [Extent3] ON [Extent3].[ID] = [Extent2].[Author_ID]
)
AS [Join1] ON [Extent1].[ID] = [Join1].[Item_ID]
WHERE 1 = [Extent1].[ID]
)
AS [Project1]
ORDER BY [Project1].[ID] ASC, [Project1].[C1] ASC
方法2给了我:
SELECT [Extent1].[ID] AS [ID], [Extent1].[Name] AS [Name]
FROM [dbo].[Authors] AS [Extent1]
WHERE EXISTS (
SELECT 1 AS [C1] FROM [dbo].[AuthoredItems] AS [Extent2]
WHERE ([Extent1].[ID] = [Extent2].[Author_ID]) AND (1 = [Extent2].[Item_ID])
)
第二种方法的sql在我的大脑上更容易。加入的次数较少等等。我认为第二种方法更有效吗?
答案 0 :(得分:1)
第一个查询似乎更“自然”且更容易理解,因为您知道项目ID,一旦找到该项目,您只需选择所有列出的作者。
在另一个查询中,如果他是该项目的作者,则查看每个作者,如果是,则选择他。
我会选择第一个。我无法确定两个查询中的速度差异,但第一个查询肯定更容易理解。