简体   繁体   English

如何通过多个字段(2个表1 PK至2 FK)加入LINQ C#Linq

[英]How to join in LINQ by multiple fields (2 TABLES 1 PK to 2 FK ) c# linq

I have 2 tables: 我有2张桌子:

  • Customers 顾客
  • ConnectedCustomers 关联客户

Connected customers table holds 2 foreign keys to Customers table and basically it looks like this: 已连接的客户表包含两个到客户表的外键,基本上看起来像这样:

在此处输入图片说明

What I'm wondering here is how can I return both customers from related table? 我想知道的是如何从相关表中退回两个客户?

I've tried something like this (NOT ALLOWED): 我已经尝试过这样的事情(不允许):

query = from c in _context.Customers join cc in _context.ConnectedCustomers
         on c.customerId equals cc.customer1_id OR c.Id equals cc.customer2.id
        select c;

And this is not allowed... so I googled little bit and I've found people are ussually working with anonymous types in this cases, so I've tried something like this: 而且这是不允许的...因此,我在Google上进行了一些搜索,发现在这种情况下,人们通常使用匿名类型,因此我尝试了以下方法:

This also did not work because I included twice c.customerId and it says anonymous type cannot have multiple properties with the same name . 这也不起作用,因为我包括了两次 c.customerId,并且它说anonymous type cannot have multiple properties with the same name

query =  from c in _context.Customers join cc in _context.ConnectedCustomers
           on new { c.customerId, c.customerId } equals new { cc.customer1_id, cc.customer2 }
        select c;

So I've removed one of c.customerId from anonymous type and it looked like this: 所以我从匿名类型中删除了c.customerId之一,它看起来像这样:

query =  from c in _context.Customers join cc in _context.ConnectedCustomers
           on new { c.customerId } equals new { cc.customer1_id, cc.customer2 }
        select c;

But than I've received error on join which said: The type of one of the expressions in the join clausule is incorrect... 但是比我收到的关于连接的错误说: The type of one of the expressions in the join clausule is incorrect...

Thanks guys ! 多谢你们 !

Cheers 干杯

sorry not entirely clear what the desired result is but I believe you want only the customers from Customers table that exist in ConnectedCustomers? 抱歉,不能完全清楚期望的结果是什么,但是我相信您只需要ConnectedCustomers中存在的“客户”表中的“客户”? If not comment to let me know and I can update, but here's what that would look like using fluent syntax: 如果没有评论让我知道,我可以进行更新,但是使用流畅的语法看起来像这样:

var myCustomers = _context.Customers.Select(c => _context.ConnectedCustomers.Any(cc => cc.customer1_id.Equals(c.customerId) || cc.customer2_id.Equals(c.customerId)).ToList();

You can either join it in 2 seperate queries and union/concat them or you can join it the "old fashiend way" by using the where condition(cross join + where condition, beware of duplicates): 您可以将其加入2个单独的查询中,并对其进行合并/合并,也可以使用where条件(交叉连接+ where条件,当心重复项)以“旧的fashiend方式”将其加入:

var query = from cust in _context.Customers 
            join custcon in _context.ConnectedCustomers
            where cust.customer_id == custcon.customer1_id
              or cust.customer_id == custcon.customer2_id
            select cust;

If you want to "return both customers from the relation table" you can simply join the customer 2 times and return a anonymous object (or a new class of your choice) containing both customers: 如果要“从关系表中退回两个客户”,则可以简单地两次加入该客户并返回包含两个客户的匿名对象(或您选择的新类):

var query = from custcon in _context.ConnectedCustomers
            join cust1 in _context.Customers on custcon.customer1_id equals cust1.customer_id
            join cust2 in _context.Customers on custcon.customer2_id equals cust1.customer_id
            select new { Customer1 = cust1, Customer2 = cust2};

From: Perform custom join operations : 来自: 执行自定义联接操作

However, the join clause cannot be used in the following cases: 但是,在以下情况下不能使用join子句:

  • When the join is predicated on an expression of inequality (a non-equijoin). 当联接基于不等式(非等联接)表示时。
  • When the join is predicated on more than one expression of equality or inequality. 当连接基于多个相等或不相等的表达式时。
  • When you have to introduce a temporary range variable for the right side (inner) sequence before the join operation. 在必须在联接操作之前为右侧(内部)序列引入临时范围变量时。

Based on the second point, your case seems to qualify as a non-equijoint . 根据第二点,您的案子似乎符合非等额资格。


So you can do a cross-joint with a where clause (here the condition is an expression, so it can be as complex as you like): 因此,您可以使用where子句进行交叉连接(此处的条件是一个表达式,因此它可以随您的意愿而复杂):

var query  = from c in _context.Customers
        from cc in _context.ConnectedCustomers
        where c.customerId == cc.customer1_id || c.customerId == cc.customer2_id
        select c.customerId;

Or simply do two equi-joins and combine them: 或者只是简单地做两个等联接并将它们组合:

var q1 = from c in _context.Customers
         join cc in _context.ConnectedCustomers
         on c.customerId equals cc.customer1_id
         select c.customerId;

var q2 = from c in _context.Customers
         join cc in _context.ConnectedCustomers
         on c.customerId equals cc.customer2_id
         select c.customerId;

var query = q1.Concat(q2);

EDIT: Fixed variable names and remove Distinct() clause since it's not specified whether you need it. 编辑:固定变量名称并删除Distinct()子句,因为未指定是否需要它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM