I'm getting a lot of duplicate joins in the SQL generated from my DbContext object using the Entity Framework. Here's my basic structure
CatalogTable( CatalogID int Primary Key )
CategoryTable( CategoryID int PRIMARY KEY, CatalogID int NOT NULL )
DepartmentTable( DepartmentID int PRIMARY KEY, CatalogID int NOT NULL)
Product( CatalogID int NOT NULL, CategoryID int NOT NULL, DepartmentID int NOT NULL )
Quite simply, a product has to have a catalog, category and department. I've setup all of the navigation properties to reflect this. Yes, a 'product' could be associated to a catalog indirectly through either the category or the department. But because there are two possible paths, I chose to explicitly indicate that a product belonged to a catalog.
So the problem becomes the EF keeps joining in these required relationships basically spitting out double joins for category and department.
Model:
//catalogs
modelBuilder.Entity<Catalog>().ToTable("Catalog.Catalogs");
modelBuilder.Entity<Catalog>().HasKey(k => k.CatalogID);
//products
modelBuilder.Entity<CatalogItem>().ToTable("Catalog.Products");
modelBuilder.Entity<CatalogItem>().HasKey(k => k.ProductID);
modelBuilder.Entity<CatalogItem>().HasRequired(req => req.CatalogCategory).WithMany().Map(m => m.MapKey("CatalogCategoryID"));
modelBuilder.Entity<CatalogItem>().HasRequired(req => req.CatalogDepartment).WithMany().Map(m => m.MapKey("CatalogDepartmentID"));
modelBuilder.Entity<CatalogItem>().HasRequired(req => req.Catalog).WithMany().Map(m => m.MapKey("CatalogID"));
//departments
modelBuilder.Entity<CatalogDepartment>().ToTable("Catalog.Departments");
modelBuilder.Entity<CatalogDepartment>().HasKey(k => k.CatalogDepartmentID);
modelBuilder.Entity<CatalogDepartment>().HasRequired(req => req.Catalog).WithMany().Map(m => m.MapKey("CatalogID"));
//categories
modelBuilder.Entity<CatalogCategory>().ToTable("Catalog.Categories");
modelBuilder.Entity<CatalogCategory>().HasKey(k => k.CatalogCategoryID);
modelBuilder.Entity<CatalogCategory>().HasRequired(req => req.Catalog).WithMany().Map(m => m.MapKey("CatalogID"));
Linq:
var query = Products
.Include(inc=>inc.CatalogCategory)
.Include(inc=>inc.CatalogDepartment)
.Include(inc=>inc.Catalog);
query.ToList();
Generated Sql:
SELECT *
FROM [Catalog].[Products] AS [Extent1]
INNER JOIN [Catalog].[Categories] AS [Extent2] ON [Extent1].[CatalogCategoryID] = [Extent2].[CatalogCategoryID]
LEFT OUTER JOIN [Catalog].[Categories] AS [Extent3] ON [Extent1].[CatalogCategoryID] = [Extent3].[CatalogCategoryID]
LEFT OUTER JOIN [Catalog].[Departments] AS [Extent4] ON [Extent1].[CatalogDepartmentID] = [Extent4].[CatalogDepartmentID]
LEFT OUTER JOIN [Catalog].[Catalogs] AS [Extent5] ON [Extent1].[CatalogID] = [Extent5].[CatalogID]
You can clearly see "Categories" being joined twice; once as an inner join and once as an outer join.
Any ideas here how to cleanly (and accurately) establish the relationships but prevent the duplicate binding? Thanks!