簡體   English   中英

linq / lambda查詢中的雙內連接?

[英]double inner join in linq/ lambda query?

我得到了這個我想要轉換為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”並顯示“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; }
}

我試圖實現的是,我將所有不同的信息放在vereniging模型中,並從那里把它作為我的休息api的輸出:

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

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

        return new JsonResult(verenigingFromRepo);

    }

我會做的功能有點不同。 像這樣:

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();
}

我個人覺得更容易看到這樣的連接並將結果合並到一個對象中

要實現與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
        });

或者使用內聯linq方法,正如Arion建議的那樣。 他的版本更具可讀性,我的版本適合那些真正喜歡lambdas,匿名類型等的人。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM