Entity framework EF如何强制内部连接?

Entity framework EF如何强制内部连接?,entity-framework,Entity Framework,我有这种风格 List<Customer> customers = db.Customers.Where( s => s.IsActive == true ) .Include( s => s.Communications.Select( a => a.Page ) ) .Include( s => s.Communications.Select( a => a.De

我有这种风格

            List<Customer> customers = db.Customers.Where( s => s.IsActive == true )
                .Include( s => s.Communications.Select( a => a.Page ) )
                .Include( s => s.Communications.Select( a => a.Dealership ) )
                .Include( s => s.Communications.Select( a => a.Lead ) )
                .ToList();
问题是左侧外部连接,因此即使通信为空,它也会返回客户。在实体类别I中,类别通信和客户也标记为[必需]。如何强制使用内部联接

这是.Include的正常行为,因为首先,它请求主数据,即客户,而不管是否存在依赖项/相关项。因此,您应该手动编写带有内部联接的查询:

var data = (from customer in db.Customers.Where(x => x.IsActive)
            join comm in db.Communications on customer.CustomerId equals comm.CustomerId1
            join page in db.Pages on comm.PageId equals page.PageId
            join dealer in db.Dealerships on comm.DealershipId equals dealer.DealershipId
            join lead in db.Leads on comm.LeadId equals lead.LeadId
            select new 
            {
                customer.CustomerId,
                comm.PageId,
                comm.DealershipId,
                comm.LeadId,

                //another required fields from any table
            }).ToList();

执行DBMS查询的较慢部分之一是将结果数据从DBMS传输到本地进程

您的客户没有或有更多的通信。每一次通信都只属于一个使用外键的客户:一个简单的一对多关系。可能是你设计了一个多对多的关系,结果会很相似

显然,您希望吸引一些客户,每个客户都有其通信的几个属性

如果使用include,则将获取完整的通信对象并将其传输到本地流程,包括其所有属性,您仅使用页面/经销商和潜在客户。您不会使用Communications.CustomerId,因为您知道它将等于Customer.Id

一般规则

仅当您计划更改/更新获取的项目时才使用“包含”。如果只想读取值,请使用选择。仅选择您真正计划使用的属性

如果Page/Devergence/Lead是类,请再次使用Select仅获取所需的属性

Page = communications.Page.Select(page => new
{
     Header = page.Header,
     Footer = page.Footer,
     Lines = page.Lines,
     ...
},
通常,实体框架中的一对多关系是使用虚拟ICollection设计的。如果您使用此属性,实体框架将知道需要内部联接,并为您执行它。这导致了相当简单的代码

如果出于某种原因,您决定不使用ICollection,那么您必须自己加入。代码将类似于:

var result = myDbcontext.Customers
    .Where(customer => customer.IsActive)       // Take only Active customers
    .GroupJoin(myDbContext.Communications,      // GroupJoin with Communications
    customer => customer.Id,                    // from every Customer take the Id
    communication => communication.CustomerId,  // from every Communication take the CustomerId
    (customer, communications) => new           // from every Customer with matching communications
    .Select(customer => new                     // make one new object
    {
        Id = customer.Id,
        Name = customer.Name,
        Communications = communications.Select(communication => new
        {
            Page = communication.Page,
            ...
        }

您不能进行所需的收集。
Page = communications.Page.Select(page => new
{
     Header = page.Header,
     Footer = page.Footer,
     Lines = page.Lines,
     ...
},
var result = myDbcontext.Customers
    .Where(customer => customer.IsActive)       // Take only Active customers
    .GroupJoin(myDbContext.Communications,      // GroupJoin with Communications
    customer => customer.Id,                    // from every Customer take the Id
    communication => communication.CustomerId,  // from every Communication take the CustomerId
    (customer, communications) => new           // from every Customer with matching communications
    .Select(customer => new                     // make one new object
    {
        Id = customer.Id,
        Name = customer.Name,
        Communications = communications.Select(communication => new
        {
            Page = communication.Page,
            ...
        }