0

Imagine a many to many relationship between Authors and Items.

There appear to be 2 broad approaches when querying for Authors of an Item (examples below).

Why might I choose one approach over the other?

Is there any difference in how the SQL is generated for the 2 queries below?

Approach One

Find the Item by ID, and then use the Authors property to list the Authors.

List<Authors> Authors = db.Items
    .Where(i => i.ID == CurrentItemID)
    .FirstOrDefault()
    .Authors.ToList();

Approach Two

Find all Authors with AuthoredItems containing the current Item's ID.

List<Authors> Authors = db.Authors
    .Where(i => i.AuthoredItems.Any(a => a.ID == CurrentItemID))
    .ToList();

Many to Many Relationship Like So:

public class Item
{
    ...
    ICollection<Author> Authors {get;set;}
}

public class Author
{
    ...
    ICollection<Item> AuthoredItems {get;set;}
}

UPDATE

As suggested I have attempted to print the generated sql for these queries.

Approach 1 gives me:

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

Approach 2 gives me:

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]) 
)

The sql from the second approach is much easier on my brain. And there's less joins etc. Am I right that the second approach would be more efficient?

Martin Hansen Lennox
  • 2,837
  • 2
  • 23
  • 64

1 Answers1

1

The first query seems more "natural" and easier to understand, because you know the item ID, and once you find the item, you just select all the listed authors.

In the other query, you look in every author if he is an author of the item, and if he is, you select him.

I would go with the first one. I can't be sure about the speed difference in the two queries but the first one is surely more simple to understand.

Mateo Velenik
  • 804
  • 1
  • 10
  • 22
  • Thanks Mateo. That was my feeling too. But I have seen enough examples of the other approach to wonder if there was any reason for preferring that. – Martin Hansen Lennox Jan 05 '14 at 12:19