多条件连接(复合键 Join)
SQL 中的多条件连接
在 SQL 中,ON 子句可以使用 AND 组合多个条件:
SELECT TOP 4 s.ID, s.Name, p.Name AS ProductName, p.Price FROM Student s
INNER JOIN Product AS p
ON s.ID = p.Sid AND s.Name = p.NameCode language: PHP (php)
LINQ 中的多条件连接
LINQ 的 join ... on ... equals ... 语法不支持直接用 && 写多个条件,而是通过创建匿名对象来实现复合键匹配:
using (var db = new DataClasses1DataContext())
{
int pageSize = 2;
int pageIndex = 4;
var query = from s in db.Student
join p in db.Product
on new { s.ID, s.Name }
equals new { ID = p.Sid, p.Name }
select new { s.ID, s.Name, DName = p.Name, p.Price };
query = query.OrderByDescending(m => m.Price);
var page = query.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
}Code language: JavaScript (javascript)
匿名对象匹配规则
两个匿名对象要能匹配,必须满足三个条件:
| 要求 | 说明 | 示例 |
|---|---|---|
| 字段名称 | 两边匿名对象的属性名必须一致 | 左边是 ID,右边也必须是 ID |
| 字段类型 | 对应属性的类型必须相同 | s.ID 是 int,p.Sid 也必须是 int |
| 字段顺序 | 属性的声明顺序也必须一致 | 先写 ID 再写 Name,两边都要先 ID 再 Name |
// 正确写法:字段名、类型、顺序都一致
new { s.ID, s.Name } equals new { ID = p.Sid, Name = p.Name }
// 错误写法:字段名不一致
new { s.ID, s.Name } equals new { Sid = p.Sid, p.Name } // 编译报错
// 错误写法:顺序不一致
new { s.Name, s.ID } equals new { ID = p.Sid, Name = p.Name } // 编译报错Code language: JavaScript (javascript)
执行逻辑
┌─────────────────────────────────────────────────────────────────┐
│ 匿名对象 A: { ID = s.ID, Name = s.Name } │
│ equals │
│ 匿名对象 B: { ID = p.Sid, Name = p.Name } │
├─────────────────────────────────────────────────────────────────┤
│ 等效于 SQL: ON s.ID = p.Sid AND s.Name = p.Name │
│ LINQ to SQL 会将其翻译为: │
│ INNER JOIN Product p ON s.ID = p.Sid AND s.Name = p.Name │
└─────────────────────────────────────────────────────────────────┘
三个及以上条件的连接
var query = from s in db.Student
join p in db.Product
on new { s.ID, s.Name, s.ClassID }
equals new { ID = p.Sid, Name = p.Name, ClassID = p.ClassID }
select new { s.ID, s.Name, p.Price };Code language: JavaScript (javascript)
关键要点
| 对比项 | SQL | LINQ |
|---|---|---|
| 单条件连接 | ON a.ID = b.ID | join b in ... on a.ID equals b.ID |
| 多条件连接 | ON a.ID = b.ID AND a.Name = b.Name | on new { a.ID, a.Name } equals new { ID = b.ID, Name = b.Name } |
| 条件运算符 | =, AND, OR 等 | 仅支持 equals,多条件通过匿名对象复合键实现 |
| OR 条件 | ON a.ID = b.ID OR a.Name = b.Name | LINQ join 不支持 OR,需用 where 替代 |
关于 OR 条件: LINQ 的
join ... on ... equals ...不支持OR语义。如果需要OR逻辑,应改用交叉连接 +where过滤:// 等效 SQL: ON s.ID = p.Sid OR s.Name = p.Name var query = from s in db.Student from p in db.Product where s.ID == p.Sid || s.Name == p.Name select new { s, p };Code language: JavaScript (javascript)
Previous: 取多少条记录Top的使用
Next: 使用实体数组进行批量连表查询