【问题标题】:How to make Exists with Dynamic Linq如何使用 Dynamic Linq 实现存在
【发布时间】:2015-06-19 17:40:48
【问题描述】:

如何使动态 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);

但是当我执行这段代码时,会出现以下异常:

“DynamicClass3”类型中不存在适用的索引器。

【问题讨论】:

    标签: c# linq entity-framework linq-to-sql dynamic-linq


    【解决方案1】:

    这似乎有效...它使用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是子查询元素,而outerItdocumento

    我已经用 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)");
    

    【讨论】:

    • 感谢您的回答,非常有帮助。
    【解决方案2】:

    Any() (https://msdn.microsoft.com/en-us/library/vstudio/bb534972%28v=vs.100%29.aspx) 可能是您应该关注的。如果可以在集合中找到至少一项满足给定谓词的项,则 Any() 将返回 True。

    我没有 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() 或结果。

    【讨论】:

      猜你喜欢
      • 2019-08-29
      • 2011-06-18
      • 2010-10-06
      • 1970-01-01
      • 2010-09-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多