So let's assume I have the following entities and their context configuration set up as follows. I have omitted a lot of properties for brevity's sake:
public class Company {
public int Id { get; set; }
public Location Location { get; set; }
}
public class Customer {
public int Id { get; set; }
public Location Location { get; set; }
}
public class Location {
public int Id { get; set; }
}
public sealed class EntityDefaultContext : DbContext {
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
modelBuilder.Entity<Company>().HasKey(m => m.Id).ToTable("Company");
modelBuilder.Entity<Company>().Property(m => m.Id).HasColumnName("Id");
modelBuilder.Entity<Company>().HasRequired(m => m.Location).WithRequiredDependent().Map(m => m.MapKey("LocationId"));
modelBuilder.Entity<Customer>().HasKey(m => m.Id).ToTable("Customer");
modelBuilder.Entity<Customer>().Property(m => m.Id).HasColumnName("Id");
modelBuilder.Entity<Customer>().HasRequired(m => m.Location).WithRequiredDependent().Map(m => m.MapKey("LocationId"));
modelBuilder.Entity<Location>().HasKey(m => m.Id).ToTable("Location");
modelBuilder.Entity<Location>().Property(m => m.Id).HasColumnName("Id");
}
}
So as you can see, both the Company and Customer entities hold a reference to the Location entity. Something that would normally be expected I believe.
I set up my DB context for just that as you can also see. But the SQL that EF generates is terribly inefficient:
SELECT
[Extent1].[Id] AS [Id],
[Extent1].[LocationId] AS [LocationId],
[Extent3].[Id] AS [Id1]
FROM
[dbo].[Customer] AS [Extent1]
LEFT OUTER JOIN [dbo].[Company] AS [Extent2] ON [Extent1].[LocationId] = [Extent2].[LocationId]
LEFT OUTER JOIN [dbo].[Company] AS [Extent3] ON [Extent1].[LocationId] = [Extent3].[LocationId]
LEFT OUTER JOIN [dbo].[Company] AS [Extent4] ON [Extent1].[LocationId] = [Extent4].[LocationId]
This is generated when I do something like this:
var q = from c in defaultContext.Set<Customer>().Include(m => m.Location)
select c;
I am doing it like this for reasons that are not relevant to the question. The weird thing is that here is the SQL if I only configure the Location entity to be associated by only the Customer entity:
SELECT
[Extent1].[Id] AS [Id],
[Extent1].[LocationId] AS [LocationId]
FROM
[dbo].[Customer] AS [Extent1]
INNER JOIN [dbo].[Location] AS [Extent2] ON [Extent1].[LocationId] = [Extent2].[Id]
Which is what I would expect. This makes me think. Does EF not support this scenario? How could it not?
Thanks in advance.
Your original mapping uses one-to-one relation. That always causes some special behavior. Moreover it has some other requirements to work correctly. What you probably want is one-to-many relation between Customer and Location and Company and Location. Change WithRequiredDependent to WithMany and it should work.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With