简体   繁体   English

ASP.NET 内核 5.0 Linq 外连接

[英]ASP.NET Core 5.0 Linq Outer Join

  • I've got Movements and Equipment ...我有MovementsEquipment ...
    • but not all Movements have Equipment .但并不是所有的Movements都有Equipment
  • 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 Movements that do have Equipment .所以,我有一个桥接表,将具有EquipmentMovements联系起来。
  • I need an OUTER JOIN so I can access all of the Movements even if they do not have any Equipment .我需要一个OUTER JOIN以便我可以访问所有Movements ,即使它们没有任何Equipment
  • ...I hope that makes sense. ...我希望这是有道理的。
  • My code below only results in Movements that have matching Equipment records in the bridge table.我下面的代码仅导致在桥表中具有匹配Equipment记录的Movements
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();
        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请参考https://docs.microsoft.com/en-gb/dotnet/csharp/linq/perform-left-outer-joins

and

http://msdn.microsoft.com/en-us/library/bb397895.aspx http://msdn.microsoft.com/en-us/library/bb397895.aspx

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();
  • You really don't want an OUTER JOIN query.你真的不想要一个OUTER JOIN查询。
  • If you want to load all Movement and all Equipment data then all you need is this:如果您想加载所有Movement和所有Equipment数据,那么您只需要以下内容:
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.上面的代码“有效”是因为实体框架DbContext会在您将数据加载到DbContext (来自ToListAsyncLoadAsync )时执行魔术,这样所有附加和加载的实体都会调用它们的引用和导航属性的设置器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM