我在SQL Server中有以下数据库结构
create table dbo.tebwf_versao
(
cd_workflow int NOT NULL,
cd_versao int NOT NULL,
nm_workflow varchar(200) NOT NULL,
constraint pkebwf_versao primary key (cd_workflow, cd_versao)
);
create table dbo.tebwf_versao_det
(
cd_workflow int NOT NULL,
cd_versao int NOT NULL,
cd_detalhe int not null,
dc_referencia varchar(200) NOT NULL,
constraint pkebwf_versao_det primary key (cd_workflow, cd_versao, cd_detalhe),
constraint fkebwf_versao_det__versao foreign key (cd_workflow, cd_versao)
references dbo.tebwf_versao (cd_workflow, cd_versao)
);
create table dbo.tebwf_versao_det_passo
(
cd_workflow int NOT NULL,
cd_versao int NOT NULL,
cd_detalhe int not null,
cd_passo smallint not null,
nm_passo varchar(200) NOT NULL,
constraint pkebwf_versao_det primary key (cd_workflow, cd_versao, cd_detalhe, cd_passo),
constraint fkebwf_versao_det_passo__versao_det foreign key (cd_workflow, cd_versao, cd_detalhe)
references dbo.tebwf_versao_det (cd_workflow, cd_versao, cd_detalhe)
);
查询我正在尝试复制以下SQL查询,并且已经将所有对象带入包含以下内容的单个Linq查询中:
select *
from dbo.tebwf_versao vs
join dbo.tebwf_versao_det vsd on vs.cd_workflow = vsd.cd_workflow
and vs.cd_versao = vsd.cd_versao
join dbo.tebwf_versao_det_passo vsdp on vsd.cd_workflow = vsdp.cd_workflow
and vsd.cd_versao = vsdp.cd_versao
and vsd.cd_detalhe = vsdp.cd_detalhe
where vs.cd_workflow = 3
and vs.cd_versao = 1
and vsd.cd_detalhe = 1
and vsdp.cd_passo = 1;
通过几个帖子,建议使用Any
命令,并构建以下查询:
var workflows = EBwfVersaos
.Include(wfv => wfv.EBwfVersaoDets
.Select(wfvd => wfvd.EBwfVersaoDetPassoes_CdDetalhe))
.Where(wfv => wfv.CdWorkflow == 3 && wfv.CdVersao == 1
&& wfv.EBwfVersaoDets.Any(wfvd => wfvd.CdDetalhe == 1 &&
wfvd.EBwfVersaoDetPassoes_CdDetalhe.Any (wfvdp => wfvdp.CdPasso == 1))).ToList();
但是,此查询不会呈现相同的结果集,因为如果我从 EBwfVersaoDets(tebwf_versao_det)中至少有一行值为1,则会从EBwfVersaos (tebwf_versao)
带来一行,但如果我在该表中有4行cd_workflow = 3
和cd_versao = 1
,但cd_detalhe
等于1,2,3和4,则所有这些行都由Linq语句返回。我想只返回值为cd_detalhe
= 1的1行。这同样适用于第二个子查询。我也试过Linq Expression:
var workflows =
(from wf in EBwfWorkflows.Where(wf => wf.CdProduto == 1 && wf.CdEvento == 1)
join wfv in EBwfVersaos.Where(wfv => wfv.CdVersao == 1)
on wf.CdWorkflow equals wfv.CdWorkflow
join wfvd in EBwfVersaoDets.Where(wfvd => wfvd.CdDetalhe == 1)
on new { wfv.CdWorkflow, wfv.CdVersao} equals new {wfvd.CdWorkflow, wfvd.CdVersao}
select new {wf = wf, wfv = wfv, wfvd = wfvd}).ToList();
它有效,但结果没有关系,我无法在它们之间轻松导航。除了下面的3个表格外,我还需要访问其他几个相关的表格,将所需的所有信息整合到一个Linq查询中,同时能够过滤,真的很痛苦,否则我会得到太多查询。有没有办法在这些多个级别上包含AND和where?
答案 0 :(得分:3)
我认为此选项在EntityFramework上不可用。但是,您可以尝试使用Entity Framework Plus:http://entityframework-plus.net/
更具体地说,您需要在Nuget Package Manager上运行以下命令:
Install-Package Z.EntityFramework.Plus.QueryIncludeFilter.EF6 -Version 1.6.0
然后,在您的代码中:
using Z.EntityFramework.Plus;
...
var workflows = _Context.EBwfWorkflows
.Where(w => w.CdProduto == 1 && w.CdEvento == 1)
.IncludeFilter(w => w.EBwfVersaos.Where(v => v.CdVersao == 1))
.Where(w => w.EBwfVersaos.Any())
它只返回"工作流程"至少有一个带有CdVersao = 1的EBwfVersao,工作流程中只有EBwfVersaos(workflow.EBwfVersaos),其中CdVersao = 1。
希望这有帮助。