LINQ - outer join to parent class in EF code first

£可爱£侵袭症+ 提交于 2019-12-12 01:23:50

问题


I am missing something fundamental here I believe.

I have the following EF code-first entities: Company and Modem. A company can have a list of modems.

 public class Company
    {
        public int ID { get; set; }
        ...
        public virtual ICollection<Modem> Modems { get; set:}
    }  


 public class Modem
    {
        public int ID { get; set; }
        ...

    }

This generates a column Company_ID as a foreign key, on the Modem table.

I want to return all modems, with their company ID, if available. In SQL I would do the following :

select * from Modem m
left outer join Company c on 
m.Company_ID = c.ID

I am familiar with doing a left outer join in LINQ using .DefaultIfEmpty() in DB-first rather than code-first.

Where my confusion arises is that I don't have m.Company_ID available in LINQ to do the join, as it is auto generated by EF.

How do I perform this join in LINQ?


回答1:


The real beauty of the EF is that you don't need to think of joins at all (well, most of the time). All you need is to properly define your entities and their relations via navigation properties. For instance, here is a definition of a model similar to yours:

public class Company
{
    public int ID { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Modem> Modems { get; set; }
}

public class Modem
{
    public int ID { get; set; }
    public string Name { get; set; }
    public virtual Company Company { get; set; }
}

public class MyDbContext : DbContext
{
    public DbSet<Company> Companies { get; set; }
    public DbSet<Modem> Modems { get; set; }
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Company>()
            .HasMany(company => company.Modems)
            .WithOptional(modem => modem.Company)
            .Map(action => action.MapKey("Company_ID"));
        base.OnModelCreating(modelBuilder);
    }
}

Note the Company.Modems and Modem.Company properties, and the fluent configuration of the relationship, including the name of the FK column.

Now, if we do the following

using (var db = new MyDbContext())
{
    var query = db.Modems.Select(m => new { Modem = m, CompanyName = m.Company.Name });
    var sqlQuery = query.ToString();
}

the sqlQuery variable contains

SELECT 
    [Extent1].[ID] AS [ID], 
    [Extent1].[Name] AS [Name], 
    [Extent1].[Company_ID] AS [Company_ID], 
    [Extent2].[Name] AS [Name1]
    FROM  [dbo].[Modems] AS [Extent1]
    LEFT OUTER JOIN [dbo].[Companies] AS [Extent2] ON [Extent1].[Company_ID] = [Extent2].[ID]

And there you go - hope you see the LEFT OUTER join you were asking for.



来源:https://stackoverflow.com/questions/33547673/linq-outer-join-to-parent-class-in-ef-code-first

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!