如何使用 Dynamic Linq 实现 Exists
How to make Exists with Dynamic Linq
如何使用动态 LINQ 创建存在?
我正在尝试使用动态 LINQ 创建 SQL 子句。我研究了很多但没有找到满意的答案。
我尝试按如下方式转换 SQL 查询:
SQL
select * from Documento where exists(
select 1 from Titulo
where Documento.codDocumento = Titulo.codDocumento
and Documento.codEmpresa = Titulo.codEmpresaDocumento
and Titulo.codFluxoConta = 'SomeValue'
and Titulo.codEmpresaFluxoConta = 'StringNumerical')
在常见的 LINQ 中,我做了如下操作:
var subquery2 = from T in db.Titulos
where T.codFluxoConta == "SomeValue"
&& T.codEmpresaFluxoConta == "StringNumerical"
select new {
codDoc = (int?)T.codDocumento,
codEmp = (string)T.codEmpresaDocumento
};
var query2 = from D in db.Documentos
where subquery2.Contains(new { codDoc = (int?)D.codDocumento, codEmp = (string)D.codEmpresa })
select new{
D.codDocumento,
D.codEmpresa
};
或
var query4 = db.Documentos.Where(d =>
(db.Titulos.Where(t => t.codFluxoConta == "SomeValue" && t.codEmpresaFluxoConta == "StringNumerical").Select(t2 => new { codDoc = (int?)t2.codDocumento, codEmp = (string)t2.codEmpresaDocumento })).Contains(new { codDoc = (int?)d.codDocumento, codEmp = (string)d.codEmpresa }));
这就是我用我的知识所做的
IQueryable linq = db.Set(T);
var exists = linq.Where("codFluxoConta == @0 && codEmpresaFluxoConta == @1", "SomeValue", "StringNumerical").Select("new(\"codDocumento\" as codDoc, \"codEmpresaDocumento\" as codEmp)");
var query = db.Documentos.Where("@0.Contains(new (it[\"codDocumento\"] as codDocumento, it[\"codEmpresa\"] as codEmpresaDocumento))", exists);
但是当我执行这段代码时,出现了以下异常:
No applicable indexer exists in type 'DynamicClass3'.
Any() (https://msdn.microsoft.com/en-us/library/vstudio/bb534972%28v=vs.100%29.aspx) 是你应该关注的。如果可以在满足给定谓词的集合中找到至少一项,则 Any() 将 return 为真。
我没有 VS 来测试这个,但这应该适合你。
db.Documento.Where(d =>
db.Titulos.Any(t =>
t.codDocumento == d.codDocumento &&
t.codEmpresaDocumento == d.codEmpresa &&
t.codFluxoConta == "" &&
t.codEmpresaFloxoConta == ""
)
);
请注意,由于您可能会使用变量与 codFluxoConta 和 codEmpresaFloxoConta 进行比较,因此在您执行查询之前它不会读取语句的值 (http://blogs.msdn.com/b/charlie/archive/2007/12/09/deferred-execution.aspx)。因此,如果您 运行 使用不同的值(例如在循环中)并保存结果,请确保 .ToList() 或值更改之前的结果。
这似乎有效...它使用 outerIt
...我不知道 Where()
中的 Any
是通过哪个魔法起作用的...
var sq = titulo.Where("codFluxoConta == @0 && codEmpresaFluxoConta == @1", "SomeValue", "StringNumerical");
var result = documento.Where("@0.Any(it.codDocumento == outerIt.codDocumento && it.codEmpresaDocumento == outerIt.codEmpresaDocumento)", sq)
.Select("new(codDocumento, codEmpresaDocumento)");
在Where()
中,it
是子查询元素,而outerIt
是documento
.
我已经使用 SQL Profiler 检查过,查询结果是:
SELECT
[Extent1].[codDocumento] AS [codDocumento],
[Extent1].[codEmpresaDocumento] AS [codEmpresaDocumento]
FROM [dbo].[Documento] AS [Extent1]
WHERE EXISTS (SELECT
1 AS [C1]
FROM [dbo].[Titulo] AS [Extent2]
WHERE (N'SomeValue' = [Extent2].[codFluxoConta]) AND (N'StringNumerical' = [Extent2].[codEmpresaFluxoConta]) AND ([Extent2].[codDocumento] = [Extent1].[codDocumento]) AND ([Extent2].[codEmpresaDocumento] = [Extent1].[codEmpresaDocumento])
)
这等同于您的查询。
请注意,在 Dynamic Linq 中,甚至可以使用 .Contains()
编写与您在 Linq 中编写的查询非常相似的查询(但请注意,我更喜欢 .Any()
而不是 .Contains()
).这两个查询使用 Entity Framework.
生成相同的 SQL 查询
var sq2 = db.Titulo.Where("codFluxoConta == @0 && codEmpresaFluxoConta == @1", "SomeValue", "StringNumerical")
.Select("new(codDocumento, codEmpresaDocumento)");
var result2 = db.Documento.Where("@0.Contains(new(outerIt.codDocumento, outerIt.codEmpresaDocumento))", sq2)
.Select("new(codDocumento as codDoc, codEmpresaDocumento as codEmp)");
如何使用动态 LINQ 创建存在?
我正在尝试使用动态 LINQ 创建 SQL 子句。我研究了很多但没有找到满意的答案。
我尝试按如下方式转换 SQL 查询:
SQL
select * from Documento where exists(
select 1 from Titulo
where Documento.codDocumento = Titulo.codDocumento
and Documento.codEmpresa = Titulo.codEmpresaDocumento
and Titulo.codFluxoConta = 'SomeValue'
and Titulo.codEmpresaFluxoConta = 'StringNumerical')
在常见的 LINQ 中,我做了如下操作:
var subquery2 = from T in db.Titulos
where T.codFluxoConta == "SomeValue"
&& T.codEmpresaFluxoConta == "StringNumerical"
select new {
codDoc = (int?)T.codDocumento,
codEmp = (string)T.codEmpresaDocumento
};
var query2 = from D in db.Documentos
where subquery2.Contains(new { codDoc = (int?)D.codDocumento, codEmp = (string)D.codEmpresa })
select new{
D.codDocumento,
D.codEmpresa
};
或
var query4 = db.Documentos.Where(d =>
(db.Titulos.Where(t => t.codFluxoConta == "SomeValue" && t.codEmpresaFluxoConta == "StringNumerical").Select(t2 => new { codDoc = (int?)t2.codDocumento, codEmp = (string)t2.codEmpresaDocumento })).Contains(new { codDoc = (int?)d.codDocumento, codEmp = (string)d.codEmpresa }));
这就是我用我的知识所做的
IQueryable linq = db.Set(T);
var exists = linq.Where("codFluxoConta == @0 && codEmpresaFluxoConta == @1", "SomeValue", "StringNumerical").Select("new(\"codDocumento\" as codDoc, \"codEmpresaDocumento\" as codEmp)");
var query = db.Documentos.Where("@0.Contains(new (it[\"codDocumento\"] as codDocumento, it[\"codEmpresa\"] as codEmpresaDocumento))", exists);
但是当我执行这段代码时,出现了以下异常:
No applicable indexer exists in type 'DynamicClass3'.
Any() (https://msdn.microsoft.com/en-us/library/vstudio/bb534972%28v=vs.100%29.aspx) 是你应该关注的。如果可以在满足给定谓词的集合中找到至少一项,则 Any() 将 return 为真。
我没有 VS 来测试这个,但这应该适合你。
db.Documento.Where(d =>
db.Titulos.Any(t =>
t.codDocumento == d.codDocumento &&
t.codEmpresaDocumento == d.codEmpresa &&
t.codFluxoConta == "" &&
t.codEmpresaFloxoConta == ""
)
);
请注意,由于您可能会使用变量与 codFluxoConta 和 codEmpresaFloxoConta 进行比较,因此在您执行查询之前它不会读取语句的值 (http://blogs.msdn.com/b/charlie/archive/2007/12/09/deferred-execution.aspx)。因此,如果您 运行 使用不同的值(例如在循环中)并保存结果,请确保 .ToList() 或值更改之前的结果。
这似乎有效...它使用 outerIt
...我不知道 Where()
中的 Any
是通过哪个魔法起作用的...
var sq = titulo.Where("codFluxoConta == @0 && codEmpresaFluxoConta == @1", "SomeValue", "StringNumerical");
var result = documento.Where("@0.Any(it.codDocumento == outerIt.codDocumento && it.codEmpresaDocumento == outerIt.codEmpresaDocumento)", sq)
.Select("new(codDocumento, codEmpresaDocumento)");
在Where()
中,it
是子查询元素,而outerIt
是documento
.
我已经使用 SQL Profiler 检查过,查询结果是:
SELECT
[Extent1].[codDocumento] AS [codDocumento],
[Extent1].[codEmpresaDocumento] AS [codEmpresaDocumento]
FROM [dbo].[Documento] AS [Extent1]
WHERE EXISTS (SELECT
1 AS [C1]
FROM [dbo].[Titulo] AS [Extent2]
WHERE (N'SomeValue' = [Extent2].[codFluxoConta]) AND (N'StringNumerical' = [Extent2].[codEmpresaFluxoConta]) AND ([Extent2].[codDocumento] = [Extent1].[codDocumento]) AND ([Extent2].[codEmpresaDocumento] = [Extent1].[codEmpresaDocumento])
)
这等同于您的查询。
请注意,在 Dynamic Linq 中,甚至可以使用 .Contains()
编写与您在 Linq 中编写的查询非常相似的查询(但请注意,我更喜欢 .Any()
而不是 .Contains()
).这两个查询使用 Entity Framework.
var sq2 = db.Titulo.Where("codFluxoConta == @0 && codEmpresaFluxoConta == @1", "SomeValue", "StringNumerical")
.Select("new(codDocumento, codEmpresaDocumento)");
var result2 = db.Documento.Where("@0.Contains(new(outerIt.codDocumento, outerIt.codEmpresaDocumento))", sq2)
.Select("new(codDocumento as codDoc, codEmpresaDocumento as codEmp)");