- I've got
MovementsandEquipment...- but not all
MovementshaveEquipment.
- but not all
- For example, a "Back Squat" requires a Barbell, Plates, etc.. but a "Pushup" doesn't require any equipment.
- So, I've got a bridge table linking the
Movementsthat do haveEquipment. - I need an
OUTER JOINso I can access all of theMovementseven if they do not have anyEquipment. - ...I hope that makes sense.
- My code below only results in
Movementsthat have matchingEquipmentrecords in the bridge table.
Movements = (
from mvmt in applicationDbContext.Movements
join mvmteq in applicationDbContext.MovementEquips on mvmt .MvmtId equals mvmteq.MvmtId
join equip in applicationDbContext.Equipment on mvmteq.EquipId equals equip .EquipId
orderby mvmt.MvmtId
select new Movement
{
MvmtId = mvmt.MvmtId,
MvmtDescr = mvmt.MvmtDescr
})
.ToList();
CodePudding user response:
var query =
from mvmt in applicationDbContext.Movements
join mvmteq in applicationDbContext.MovementEquips on mvmt.MvmtId
equals mvmteq.MvmtId
join equip in applicationDbContext.Equipment on mvmteq.EquipId equals
equip.EquipId into g
from mvmteq in g.DefaultIfEmpty()
where mvmt.MvmtId != null
select new
{
MvmtId = mvmt.MvmtId,
MvmtDescr = mvmt.MvmtDescr
}).ToList();
Please refer to https://docs.microsoft.com/en-gb/dotnet/csharp/linq/perform-left-outer-joins
and
http://msdn.microsoft.com/en-us/library/bb397895.aspx
CodePudding user response:
- You really don't want an
OUTER JOINquery. - If you want to load all
Movementand allEquipmentdata then all you need is this:
static async Task<( IReadOnlyList<Movement> allMovements, IReadOnlyList<Equipment> allEquipment )> LoadEverythingAsync( this ApplicationDbContext db, CancellationToken cancellationToken )
{
IReadOnlyList<Movement> allMovements;
IReadOnlyList<Equipment> allEquipment;
{
List<Movement> mov = await db.Movements.ToListAsync( cancellationToken ).ConfigureAwait(false);
List<Equipment> eqp = await db.Equipment.ToListAsync( cancellationToken ).ConfigureAwait(false);
await db.MovementEquips.LoadAsync( cancellationToken ).ConfigureAwait(false);
allMovements = mov;
allEquipment = eqp;
}
return ( allMovements, allEquipment );
}
The code above "works" because the Entity Framework DbContext performs magic whenever you load data into the DbContext (from both ToListAsync and LoadAsync) such that all attached and loaded entities will have their reference and navigation properties' setters invoked.
CodePudding user response:
Movements = (
from mvmt in applicationDbContext.Movements
join mvmteq in applicationDbContext.MovementEquips on mvmt.MvmtId equals mvmteq.MvmtId into join_1
from mvmteq in join_1.DefaultIfEmpty()
join equip in applicationDbContext.Equipment on mvmteq.EquipId equals equip.EquipId into join_2
from equip in join_2.DefaultIfEmpty()
select new GetMovementRequest
{
MvmtId = mvmt.MvmtId,
MvmtDescr = mvmt.MvmtDescr,
MvmtMetrics = mvmt.MvmtMetrics,
MvmtStandard = mvmt.MvmtStandard,
EquipId = equip.EquipId,
EquipDescr = equip.EquipDescr
}
).ToList();
