【问题标题】:double inner join in linq/ lambda query?linq/lambda 查询中的双内连接?
【发布时间】:2017-10-10 09:50:41
【问题描述】:

我得到了想要转换为 Linq 的 SQL 查询。 这是联系方式:

我正在制作一个需要从 3 个不同表返回值的 asp.net api

CREATE TABLE Locatie (
   locatieId            INT IDENTITY(1,1)    not null,
   postcode             VARCHAR(10)          not null,
   huisnummer           INT                  not null,
   adres                VARCHAR(50)          not null,
   plaats               VARCHAR(50)          not null,




CREATE TABLE Vereniging (
   verenigingId         INT IDENTITY(1,1)    not null,
   locatieId            INT                  not null,
   naam                 VARCHAR(50)          not null,
   facebookGroupId      BIGINT               null,


CREATE TABLE Saldo (
   saldoId              INT IDENTITY(1,1)    not null,
   lidId                INT                  not null,
   verenigingId         INT                  not null,
   bedrag               SMALLMONEY           not null,

我省略了所有外键和主键。这只是为了澄清我想要的。我现在的问题是我有一个需要从多个表中返回信息的函数。 sql 查询如下所示=

Select v.verenigingId, l.postcode, l.huisnummer, l.adres,l.plaats,v.naam,v.facebookGroupId 
from Vereniging v inner join Saldo s
on v.verenigingId = s.verenigingId
inner join Locatie l
on v.locatieId=l.locatieId
where s.lidId = 1;

我从 lidid=1 得到所有“verenigingen”,并在表 Location 中显示“verenigingen”的所有信息。

但是当我尝试使用 linq/lambda 执行此操作时,它会出错; 我的函数如下所示:

public class LibraryRepository : ILibraryRepository
{
    private LibraryContext _context;

    public LibraryRepository(LibraryContext context)
    {
        _context = context;
    }

    public bool Save()
    {
        return (_context.SaveChanges() >= 0);
    }

    public IEnumerable<Verenigingmodel> GetVerenigingenperLid(int lidId)
    {
        return _context.Vereniging
            .Join(
                _context.Saldo.Where(b => b.lidId == lidId),
            ver => ver.verenigingId,
                sal => sal.verenigingId,
                (ver, sal) => new Viewmodel { Vereniging = ver, Saldo = sal })
            .Join(
                _context.Locatie,
                verr => verr.Vereniging.locatieId,
                loca => loca.locatieId,
                (vr, loca) => new Viewmodel { Locatie = loca });
                //this returns wrong sql information
    }

}

我的 verenigingmodel 看起来像这样:

public class Verenigingmodel
{
    public int verenigingId { get; set; }
    public string postcode { get; set; }
    public int huisnummer { get; set; }
    public string adres { get; set; }
    public string plaats { get; set; }
    public string naam { get; set; }
    public int facebookGroupId { get; set; }
}

我的库上下文如下所示:

public class LibraryContext : DbContext
{
    public LibraryContext(DbContextOptions<LibraryContext> options)
       : base(options)
    {
        Database.Migrate();
    }

    public DbSet<Gebruiker> Gebruiker { get; set; }
    public DbSet<Lid> Lid { get; set; }
    public DbSet<Vereniging> Vereniging { get; set; }
    public DbSet<Saldo> Saldo { get; set; }
    public DbSet<Locatie> Locatie { get; set; }
}

我想要实现的是,我将所有不同的信息放入 verenigingmodel 中,然后将其作为我的 rest api 的输出:

    [HttpGet("api/Vereniging/{lidId}")]

    public IActionResult FindVereniGingenPerLid(int lidId)
    {
        var verenigingFromRepo = vlibraryRepository.GetVerenigingenperLid(lidId);

        return new JsonResult(verenigingFromRepo);

    }

【问题讨论】:

  • 我猜,它返回空的ViewModel,只有Locatie 填充?还是有其他问题?

标签: c# mysql sql-server linq lambda


【解决方案1】:

我会做的功能有点不同。像这样:

public IEnumerable<Verenigingmodel> GetVerenigingenperLid(int lidId)
{
    return (
        from v in _context.Vereniging
        join s in _context.Saldo
            on v.verenigingId equals s.verenigingId
        join l in _context.Locatie
            on v.locatieId equals l.locatieId
        select new Verenigingmodel()
        {
            verenigingId= v.verenigingId,
            postcode=l.postcode,
            huisnummer=l.huisnummer,
            adres=l.adres,
            naam=v.naam,
            facebookGroupId=v.facebookGroupId,
            plaats=l.plaats
        }
     ).ToList();
}

我个人觉得这样更容易看到连接并将结果组合到一个对象中

【讨论】:

  • 感谢您的回答!这正是我需要的!
  • @louisschrauwen 欢迎来到 StackOverflow。如果您觉得答案有用,请点赞,如果答案有助于您解决问题,请将其标记为答案(在答案总票数下方打勾)
【解决方案2】:

要实现等同于 sql 查询的行为,你应该修改你的代码如下:

return _context.Vereniging
    .Join(
        _context.Saldo.Where(b => b.lidId == lidId),
        v => v.verenigingId,
        s => s.verenigingId,
        (v, s) => new { Vereniging = v, Saldo = s })
    .Join(
        _context.Locatie,
        v => v.Vereniging.locatieId,
        l => l.locatieId,
        (v, l) => 
        new Verenigingmodel 
        {
            verenigingId = v.Vereniging.id,
            postcode = l.postcode,
            huisnummer = l.huisnummer,
            adres = l.adres,
            plaats = l.plaats,
            naam = v.Vereniging.naam,
            facebookGroupId = v.Vereniging.facebookGroupId
        });

或者按照 Arion 的建议使用内联 linq 方法。他的版本更具可读性,我的版本是为那些真正喜欢 lambdas、匿名类型等的人准备的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-03
    相关资源
    最近更新 更多