EF中的多表连接

时间:2015-06-17 16:04:57

标签: entity-framework

在SQL Server中,我有这个查询:

SELECT cvs.* 
  FROM dbo.ClientVoiceSetup cvs
 WHERE cvs.EnrollmentCode = 74311
/** Apply Vendor Data Scope **/
   AND cvs.ClientID IN (
SELECT DISTINCT cc.client_id
  FROM cli_case cc
 INNER JOIN cli_case_plan     ccp ON  cc.case_id         = ccp.case_id
 INNER JOIN service_plan       sp ON ccp.service_plan_id =  sp.service_plan_id
 INNER JOIN VendorServicePlan vsp ON  sp.service_plan_id = vsp.ServicePlanID
/** Apply Vendor ID from login **/
 WHERE vsp.VendorID = 4)

注意:在SQL中,客户端< - > cli_case< - > cli_case_plan没有定义任何FK。 service_plan< - > VendorServicePlan< - >供应商 do 定义了FK,其中VendorServicePlan仅为多对多连接表。

子查询是一个数据范围过滤器,将应用于多个不同的调用。当我将DB拖入EF时,我的结构略有不同。我有以下实体:

客户端 cli_case cli_case_plan service_plan(带有供应商ICollection) 供应商(带有service_plan ICollection)

我在代码中创建了以下JOIN:

var q = (from cc in context.cli_case
    join ccp in context.cli_case_plan on cc.case_id equals ccp.case_id
    join sp in context.service_plan on ccp.service_plan_id equals sp.service_plan_id
    select cc.client_id);
return q.ToList();

我在如何添加" WHERE子句" for VendorID == myInput。

作为旁注:我想知道如何返回非物质化EF语句而不是DB调用的结果。长期的想法是将此声明作为过滤器注入到正常的" EF调用所以当它实现时它包括过滤。 (为什么在可以调用一次时调用数据库两次?)除非有更好的方法?

1 个答案:

答案 0 :(得分:0)

想出来。

LINQ for SQL

var p = (from cc in context.cli_case
         join ccp in context.cli_case_plan on cc.case_id equals ccp.case_id
         join sp in context.service_plan on ccp.service_plan_id equals sp.service_plan_id
         where sp.Vendors.Any(a => a.VendorID == vendorId)
         select cc.client_id);

LINQ for Objects

    var q = context.cli_case.Join(context.cli_case_plan, cc => cc.case_id, ccp => ccp.case_id, (cc, ccp) => new {cc, ccp})
        .Join(context.service_plan, @t => @t.ccp.service_plan_id, sp => sp.service_plan_id, (@t, sp) => new {@t, sp})
        .Where(ven => ven.sp.Vendors.Any(a => a.VendorID == vendorId))
        .Select(a => a.@t.cc.client_id);

然后我可以将其作为IQuerayble< int>并进一步使用它:

var enrollmentCode = 13524;
// provides the underlying SQL, does not hit the DB...
var clientList = db.GetClientIdListFromVendorId(4);
// set WHERE clause to filter on enrollmentCode and allowed client list...
var q = db.ClientSetups
          .Where(a => a.EnrollmentCode == enrollmentCode
                   && clientList.Contains(a.ClientID))
          .ToList();