如何在 EF 中指定左连接?

Posted

技术标签:

【中文标题】如何在 EF 中指定左连接?【英文标题】:How to specify left join in EF? 【发布时间】:2012-10-17 06:59:50 【问题描述】:

我的模特:

public partial class history_builds

    public int ID  get; set; 
    public int build  get; set; 
    public int br  get; set; 
    public int tag  get; set; 
    public string line  get; set; 
    public int rev  get; set; 
    public int user_ID  get; set; 
    public string distrib_path  get; set; 
    public string setup_path  get; set; 
    public System.DateTime build_date  get; set; 
    public string product  get; set; 


public partial class history_uploads

    public int ID  get; set; 
    public int ID_user  get; set; 
    public string Line  get; set; 
    public int Build  get; set; 
    public string Distrib  get; set; 
    public System.DateTime Time_upload  get; set; 
    public int Status  get; set; 


public partial class user

    public int ID  get; set; 
    public string Name  get; set; 
    public int ID_group  get; set; 

上下文:

public DbSet<history_builds> history_builds  get; set; 
public DbSet<history_uploads> history_uploads  get; set; 
public DbSet<user> users  get; set; 

我尝试像这样Entity framework left join 进行左连接

var items = entities.history_builds
    .Join(
        entities.users.DefaultIfEmpty(),
        hb => hb.user_ID,
        u => u.ID,
        (hb, u) =>
            new 
                hb.distrib_path,
                hb.setup_path,
                hb.build_date,
                hb.build,
                User = (u == null ? String.Empty : u.Name),
                hb.rev
            
    )
    .Join(entities.history_uploads.DefaultIfEmpty(),
        hb => hb.build,
        hu => hu.Build,
        (hb, hu) =>
            new HistoryBuidItem 
                Revision = hb.rev,
                Build = hb.build,
                DistribPath = hb.distrib_path,
                SetupPath = hb.setup_path,
                BuildDate = hb.build_date,
                User = hb.User,
                IsUpload = (hu == null ? true : false)
            
    )
    .Where(x => ids.Contains(x.Revision))
    .ToList();

但是不行,EF还是发出inner join sql代码,怎么回事?

【问题讨论】:

【参考方案1】:

您应该为此使用GroupJoin。

看一下例子:

var customers = db.Customer
                  .GroupJoin(db.SpecialCustomer, c => c.ID, g => g.CustomerId, (f, b) => new  f, b )
                  .SelectMany(z => z.b.DefaultIfEmpty(), (z, g) => new  z, g );

【讨论】:

【参考方案2】:

左外连接示例:

from c in table0
join o in table1 on c.sno equals o.sno into ps
from o in ps.DefaultIfEmpty()
select new  c.name, o.number

渲染SQL:

SELECT [t0].[name], [t1].[number] AS [number]
FROM [table0] AS [t0]
LEFT OUTER JOIN [table1] AS [t1] ON ([t0].[sno]) = [t1].[sno]    

【讨论】:

【参考方案3】:

唐春浩回答的更简单的版本:

from c in table0
from o in table1.Where(x => c.sno == x.sno).DefaultIfEmpty()
select new  c.name, o.number 

【讨论】:

以上是关于如何在 EF 中指定左连接?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 EF / EF Core 中的第二个表上实现具有某些条件的左连接?

EF的左连接查询

EF Core 左连接计数

EF Core Navigation Property Include 使用左连接而不是内连接

LINQ EF Core 左连接 [重复]

mysql连接内连接左连接右连接全连接