A little bit of preface: I am working in EF Core 6 and was trying to create an SQL query using the Fluent API. The raw SQL query that I am trying to achieve is:
SELECT *
FROM [table] AS [t]
LEFT JOIN [table0] AS [t0] ON [t].[field1] = [t0].[field1]
LEFT JOIN [table1] AS [t1] ON [t].[field2] = [t1].[field2] AND [t1].[field3] = [t0].[field3]
LEFT JOIN [table2] AS [t2] ON [t1].[field4] = [t2].[field4]
WHERE ([t0].[field5] = GUID)
I have the following in EF Core:
var query = db.Table
.Include((e) => e.Table0Navigation)
.Include((e) => e.Table1Navigation)
.Include((e) => e.Table1Navigation.Table2Navigation)
.Where((e) => e.Table0Navigation.GUID == request.GUID)
Here are the models for the schemas (extraneous fields removed)
Table:
[Key]
public int field0 { get; set; }
[ForeignKey("field1")]
public int field1 { get; set; }
[ForeignKey("field2")]
public string field2 { get; set; } = null!;
public Table1? Table1Navigation { get; set; }
public Table0 Table0Navigation { get; set; } = null!;
Table0:
[Key]
public int field1 { get; set; }
public int? field3 { get; set; }
public GUID field5 { get; set; }
Table1:
public int field3 { get; set; }
public string field2 { get; set; } = null!;
public int? field4 { get; set; }
public Table2 Table2Navigation { get; set; } = null!;
Table2:
public int field4 { get; set; }
The relationships/model in the context I have defined for Table 1's entity is:
entity.HasKey((e) => new { e.field2 });
entity
.HasMany((e) => e.TableNavigation) //Navigation from Table 1 to Table
.WithOne((e) => e.Table1Navigation) //Navigation from Table to Table 1
.HasForeignKey((e) => e.field2) //Represents Table
.HasPrincipalKey((e) => e.field2) //Represents Table 1
.IsRequired(false); //Needed for LEFT JOIN
entity
.HasMany((e) => e.Table0Navigation) //Represents navigation from Table 1 to Table 0
.WithOne((e) => e.Table1Navigation) //Represents navigation from Table 0 to Table 1
.HasForeignKey((e) => e.field1) //Represents Table 0
.HasPrincipalKey((e) => e.field1) //Represents Table 1
.IsRequired(false); //Needed for LEFT JOIN
The other tables do not have relationship definitions defined in the model.
Important to note that it is possible for Table to have a
field2with value but Table 1 does not have a corresponding record that containfield2, but the result should still be returned, just the values normally gotten from the record in Table 1 would beNULLfield3is coming from Table 0 (t0) on a join between Table (t) and Table 1 (t1)
The problem that I am facing is that I can never manage to get it to do the join on both conditions, it can do it properly on the field2 but I can never get it to do it on field3
Ive tried pretty much everything but still can't figure out, maybe on of you could help?
Thank you in advance.
Includeisn't used to perform JOINs, it's used to eagerly load related objects that aren't included in theSelectexpression.do not have relationship definitionsthey should be added then.OnModelConfiguring.IncludeandSelectuse those relations to generate JOINs. It's unclear whatTable 1 does not have a corresponding record that contain field2means right now. Are you trying to define a relation on a non-primary key field?Table 1 does not have a corresponding record that contain field2it is a bit complex since the specific value of the field that we want to do the JOIN on does NOT necessarily exist in Table 1. So you could have a table t with a record like so: (field0 | field1 | ... | field2) (a | b | | c) It is possible for Table t2 to NOT have a record that contains the same value for field2 as in table 1, i.e in this case, the table t2 does not have a record with field2 value c (field3 | field2 | field4) (d | e | f)