Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/77.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将linq with All转换为SQL_Sql_Linq_Tsql - Fatal编程技术网

将linq with All转换为SQL

将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

我有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> 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
    )
)