0

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!

BlackjacketMack
  • 5,472
  • 28
  • 32
  • And what Linq query did you use to get that SQL? – Ladislav Mrnka Jun 17 '12 at 08:36
  • Hi Ladislav, I cleaned up the examples a bit. Thanks. – BlackjacketMack Jun 17 '12 at 12:28
  • 1
    possible duplicate of [Simple Linq query has duplicated join against same table?](http://stackoverflow.com/questions/4476595/simple-linq-query-has-duplicated-join-against-same-table) In the first answer someone from EF team confirmed that this is a bug. From the comments below that answer (James Crowley who apparently tested it) I would conclude that the bug has be fixed in June 2011 CTP which means that it likely will be fixed in EF 5 since the features (all?) of June CTP are moved into the EF 5 release. Sure I am not. I can't find an official confirmation from the EF team. – Slauma Jun 17 '12 at 12:58
  • Thanks Slauma. I spent a good chunk of time trying to make sure I wasn't asking a dupe. Maybe I was focused on EF instead of 'Linq'. In any case, thanks very much. I guess I'll just wait until the fix comes out. – BlackjacketMack Jun 17 '12 at 14:44
  • Well, you don't need to stop your project until EF 5 (just saying in case you meant "wait until" that radical :)). The SQL is stupid and contains redundant bits but it is not wrong and returns correct results after all. Perhaps even the query engine of SQL Server "optimizes" the duplicate join away. I guess the performance hit is minimal. – Slauma Jun 17 '12 at 14:58

0 Answers0