How to do I make exists with dynamic LINQ?
I'm trying to create an SQL clause with dynamic LINQ. I researched a lot of and not found an satisfactory answer.
I try convert the SQL query as follows:
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')
In common LINQ I did as follows:
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
};
or
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 }));
And this is what I did with my knowledge
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);
But when I execute this code the following exception occurs:
No applicable indexer exists in type 'DynamicClass3'.
This seems to work... It uses
outerIt
... and I don't know through which magic theAny
inside theWhere()
works...in the
Where()
,it
is the subquery element, whileouterIt
is thedocumento
.I've checked with the SQL Profiler and the result of the query is:
that is equivalent to your query.
Note that in Dynamic Linq it is even possible to write a query much similar to the one you wrote in Linq, using
.Contains()
(but note that I do prefer the.Any()
to the.Contains()
). The two queries produce the same SQL query with Entity Framework.