使用实体框架中的Linq仅使用外键的左外连接

时间:2017-10-27 00:09:47

标签: c# entity-framework linq

我需要在两个表(表A和表B)上执行左外连接。但表B是TableA和表C之间的连接列,只有两列都是外键。其中一列是表A的主键,另一列是表C的外键。

我如何外连接表,因为Entity Framework不会创建一个名为TableB的对象?我使用的是数据库优先方法。

from a in db.tableA
join b in (no Table B object) on a.Id equals b.userId into group1
from g1 in group1.DefaultIfEmpty()
select new { id = g1.Id, userId = g1.userId }

This是一个不同的问题,但是这个问题在无法使用两个外键为表创建对象方面也有类似的问题。

1 个答案:

答案 0 :(得分:1)

显然,表A中的元素与表B中的元素之间存在多对多关系:每个A都有零个或多个B,每个B属于零个或多个As。

(这里:A的复数,B是B的复数)

你是对的,在关系数据库中,使用第三个表实现了多对多关系,通常称为联结表。

你是对的,如果你在实体框架中为多对多关系设计了你的A类和B类,你就无法访问联结表。

幸运的是,您不需要联结表!

如果您为entity framework many-to-many relation正确设置了类,则它们将如下所示

class A
{
    public int Id {get; set;}

    // every A has zero or more Bs:
    public virtual ICollection<B> Bs {get; set;}

    ... //  other properties
}
class B
{
    public int Id {get; set;}

    // every B belongs to zero or more As:
    public virtual ICollection<A> As {get; set;}

    ... //  other properties
}
class MyDbContext : DbContext
{
    public DbSet<A> As {get; set;}
    public DbSet<B> Bs {get; set;}
} 

这足以告诉实体框架您想要设计As和B之间的多对多关系。

虽然您没有提到联结表,但实体框架知道需要联结表并为您创建。

您可能希望在桌面上使用A元素和包含B元素的表格进行左外连接,因为您需要以下内容:

  

给我表A中的所有元素......所有的B都有......

如果您正在使用SQL,那么您将使用联结表执行表A的左外连接,并使用表B进行某种连接。之后,您将执行所需的WHERE以获取结果。

使用实体框架时,您不需要联结表:

var result = myDbContext.As
    .Where(a => <predicate with the As you want in the result>)
    .Select(a => new
    {
        ... // properties from A that you want

        Bs = a.Bs.Where(b => <predicate with the Bs from A you want>)
    }

因为您使用每个A中的B,实体框架将知道必须使用联结表完成联接。因为A可能有零B,实体框架将使用左外连接。