0

I have an issue where the Sql generated from a Graphql request is using an inner join that is causing data to be skipped. This is because the join is happening on an id field that can be null. I have no control over the id field so I cannot just make the field not-null. I have re-written the Sql exchanging the inner join for a left join and it works as desired but I cannot figure out how to get Hot Chocolate to do the same.

Example of relationship (not actual code being worked with):

public class Person {
  public Guid PersonId {get;set;}
  public string Name {get;set;}
  public Guid CarId {get;set;}
  public virtual Car OwnedCar {get;set}
}

public class Car {
  public Guid CarId {get;set;}
  public string Brand {get;get;}
  public virtual ICollection<Person> OwnersOfThisTypeOfCar {get;set;}
}

At the database context I have a many to one relationship set up like

protected override void OnModelCreating(ModelBuilder modelBuilder)
//code omitted for brevity
modelBuilder.Entity<Car>(entity => {
  //code omitted for brevity
  entity.HasMany(d => d.OwnersOfThisTypeOfCar)
       .WithOne(p => p.OwnedCar)
       .HasForeignKey(p => p.CarId);

});

when making a Graphql request like:

{person() {name, ownedCar{ brand }}} 

I expect to get back all people in the DB and the car they own or null for the car if they don't have one. So I expect the Sql generated to look like

Select t.name, t1.brand from people as t 
left join cars as t1 on t.carId = t1.carId;

Instead I get

Select t.name, t1.brand from people as t 
inner join cars as t1 on t.carId = t1.carId;

which, of course only returns the people that have cars.

I feel that there is some simple solution that would allow Hot Chocolate to specify that the field / type only be populated when it is not null (thereby informing EfCore to use a left join) but I just can't find it. Any help in this would be greatly appreciated as I have spent quite a few hours trying to figure it out.

ZackR
  • 61
  • 1
  • 7

1 Answers1

0

For anyone that runs into this the solution is to add an .IsRequired(false); to the end of your entity builder so:

  entity.HasMany(d => d.OwnersOfThisTypeOfCar)
   .WithOne(p => p.OwnedCar)
   .HasForeignKey(p => p.CarId)
   .IsRequired(false);
ZackR
  • 61
  • 1
  • 7