Could queries with navigation properties not produce joins if using only primary keys?
- Dominant language
- C#
- Stars
- 14.8k
- Forks
- 3.4k
- PR merge metrics
- PR metrics pending
Description
I have a model like this:
```C#
public class Warranty {
// Primary key in Fluent API
public int Id { get; set; }
// DATA
[...]
// Navigation
public ICollection? Conditions { get; set; }
}
public class WarrantyCondition {
// Composite key in Fluent API
public int WarrantyId { get; set; }
public int Id { get; set; }
// DATA
[...]
// Navigation
public Warranty? Warranty{ get; set; }
public ICollection? Products { get; set; }
}
public class WarrantyProduct {
// Composite key in Fluent API
public int ConditionWarrantyId { get; set; }
public int ConditionId { get; set; }
public int ProductId { get; set; }
// DATA
[...]
// Navigation
public WarrantyCondition? Condition { get; set; }
public Product? Product { get; set; }
}
```
With tables looking like this:



When querying by using a navigation property like this:
```C#
dbContext.Set().Where(p => p.Condition.Warranty.Id == 1).ToArray()
```
I get a resulting query like this:
```SQL
SELECT [w].[ConditionWarrantyId], [w].[ConditionId], [w].[ProductId], [w].[ExtensionId], [w].[PartialPrice]
FROM [WarrantyProducts] AS [w]
INNER JOIN [WarrantyCondition] AS [w0] ON ([w].[ConditionWarrantyId] = [w0].[WarrantyId]) AND ([w].[ConditionId] = [w0].[Id])
INNER JOIN [Warranties] AS [w1] ON [w0].[WarrantyId] = [w1].[Id]
WHERE [w1].[Id] = 1
```
Even though all the primary keys are already stored in the WarrantyProducts table, so the two joins should not be needed.
Ok, I could just query on the exposed keys instead of navigation properties, but I was trying to auto-generate the foreign primary keys as shadow properties only, and I came across this result which invalidates performance.
Would it be too complicated to extract the conditions and check if they only consist of foreign keys?
Here's what I was trying to do: auto-generated foreign primary keys
This is what I had in mind, and it works, I think this would greatly consolidate EF as it would avoid repeating foreign keys
```C#
public class Warranty {
// Primary key in Fluent API
public int Id { get; set; }
// DATA
[...]
// Navigation
public ICollection? Conditions { get; set; }
}
public class WarrantyCondition {
// Composite key in Fluent API (recursively retrieves keys from the navigations)
public Warranty? Warranty{ get; set; }
public int Id { get; set; }
// DATA
[...]
// Navigation
public ICollection? Products { get; set; }
}
public class WarrantyProduct {
// Composite key in Fluent API (recursively retrieves keys from the navigations)
public WarrantyCondition? Condition { get; set; }
public Product? Product { get; set; }
// DATA
[...]
}
```
Contributor guide
Assessment
This issue has not been assessed yet.