将linq with All转换为SQL
我有A、B和C表 B与A的关系是多对一 我想找到所有A,其中C是B的完整子集 下面的LINQ查询(伪代码)表示我想要得到的内容将linq with All转换为SQL,sql,linq,tsql,Sql,Linq,Tsql,我有A、B和C表 B与A的关系是多对一 我想找到所有A,其中C是B的完整子集 下面的LINQ查询(伪代码)表示我想要得到的内容 class A { public B[] Bs { get; set; } } class B { public string Text { get; set; } } class C { public string Text { get; set; } } private static IEnumerable<A> Searc
class A
{
public B[] Bs { get; set; }
}
class B
{
public string Text { get; set; }
}
class C
{
public string Text { get; set; }
}
private static IEnumerable<A> Search(C[] C, A[] A)
{
return from a in A
where C.All(c => a.Bs.Any(b => SomeCondition(b, c)))
select a;
}
private static bool SomeCondition(B b, C c)
{
//There we comparing B and C
throw new NotImplementedException();
}
我需要得到所有A,其中B匹配所有C
范例
A | a_ID |
| 1 |
| 2 |
| 3 |
B | b_ID | a_ID | Text |
| 1 | 1 | Cat |
| 2 | 1 | Dog |
| 3 | 1 | Rabbit|
| 4 | 2 | Cat |
| 5 | 2 | Cat | -- B can contain duplicates
| 6 | 2 | Rabbit|
C | c_ID | Text |
| 1 | Cat |
| 2 | Dog |
输出
| a_ID |
| 1 |
更新3:计数不同的c\u id
SELECT b.a_id
FROM b
JOIN c ON b.Text = c.Text
GROUP BY b.a_id
HAVING COUNT(distinct c.c_id) = (SELECT COUNT(*) FROM C)
输出:
| A_ID |
--------
| 1 |
这是一个好的,我知道怎么做了 假设
x=>x.All(e=>predicate(e))
可以转换为x=>!x、 任意(e=>!谓词(e))
我们可以将原始表达式转换为下面的表达式
from a in A
where !C.Any(c => !a.Bs.Any(b => SomeCondition(b, c)))
select a;
可以使用exists
关键字将任何数据转换为SQL
我假设SomeCondition
正好相等
首先转换!a、 任何(b=>SomeCondition(b,c))
到SQL
NOT EXISTS (
SELECT 1 FROM B b
WHERE a.a_id = b.a_id -- a will be added later
AND c.Text = b.Text -- c will be added later
)
下一个转换!C.Any(C=>!a.Bs.Any(b=>SomeCondition(b,C)))
最后是整个表情
SELECT * FROM A a
WHERE NOT EXISTS (
SELECT 1 FROM C c
WHERE NOT EXISTS (
SELECT 1 FROM B b
WHERE a.a_id = b.a_id
AND c.Text = b.Text
)
)
现在我们可以做一些优化了@t这是一个伪代码,没有足够的信息来理解这个问题。若它将编译,那个么它可能是。你们能提供表的DDL和所需的输出吗?你们使用的是什么linq提供程序?LINQ2SQL?EF?@andri我没有使用linq provider,这是我需要在SQLIt中编写的伪代码。它将在C中的任何B处选择A。不是全部。谢谢@peterm是否有任何可能避免计数(*)?实际上这里不需要与A连接公平
与A连接是冗余的。更新了答案。不,在我的查询版本中,您无法避免计数。但它只执行一次,而且速度很快。顺便说一句,如果C.Text
为NULL
可以使用从C中选择COUNT(Text)
按COUNT固定(不同的C.C\u id)
NOT EXISTS (
SELECT 1 FROM C c
WHERE NOT EXISTS (
SELECT 1 FROM B b
WHERE a.a_id = b.a_id -- a will be added later
AND c.Text = b.Text
)
)
SELECT * FROM A a
WHERE NOT EXISTS (
SELECT 1 FROM C c
WHERE NOT EXISTS (
SELECT 1 FROM B b
WHERE a.a_id = b.a_id
AND c.Text = b.Text
)
)