I am trying to get a left join working in Linq using ASP.NET Core and EntityFramework Core.
Simple situation with two tables:
If you need to do the Left joins then you have to use into
and DefaultIfEmpty()
as shown below.
var result = from person in _dbContext.Person
join detail in _dbContext.PersonDetails on person.Id equals detail.PersonId into Details
from m in Details.DefaultIfEmpty()
select new
{
id = person.Id,
firstname = person.Firstname,
lastname = person.Lastname,
detailText = m.DetailText
};
You can learn more about it : Left Outer Join in LINQ to Entities
You not doing left join, the linq which you are using is basically creating a inner join. For left join in linq use into keyword
[HttpGet]
public IActionResult Get()
{
var result = from person in _dbContext.Person
join detail in _dbContext.PersonDetails on person.Id equals detail.PersonId
into Details
from defaultVal in Details.DefaultIfEmpty()
select new
{
id = person.Id,
firstname = person.Firstname,
lastname = person.Lastname,
detailText = defaultVal.DetailText
};
return Ok(result);
}
I agree to author of this post - it is still look like a bug! If you have empty joined tables you always receive "Object reference not set to an instance of an object.". The only way is to check joined tables to null:
IEnumerable<Models.Service> clubServices =
from s in services
from c in clubs.Where(club => club.ClubId == s.ClubId).DefaultIfEmpty()
from t in clubs.Where(tenant => tenant.TenantId == c.TenantId).DefaultIfEmpty()
select new Models.Service
{
ServiceId = s.ServiceId.ToString(),
ClubId = c == null ? (int?)null : c.ClubId,
ClubName = c == null ? null : c.Name,
HasTimeTable = s.HasTimeTable,
MultipleCount = s.MultipleCount,
Name = s.Name,
Tags = s.Tags.Split(';', StringSplitOptions.RemoveEmptyEntries),
TenantId = t == null ? (int?)null : t.TenantId,
TenantName = t == null ? null : t.Name
};
I unable to check "detailText = person.PersonDetails.Select(d => d.DetailText).SingleOrDefault()
" because my joined tables are in different DB.