Linq组通过分组错误的结果集

时间:2015-11-10 19:57:02

标签: c# sql-server entity-framework linq entity-framework-6

研究员,

我从来没有遇到过与此问题差不多的问题,并且没有在整个互联网上找到任何答案...

我有一个简单的查询:

var data = (from b in db.vw_SpedF500
                    where b.DATABAIXA >= dtInicial && b.DATABAIXA <= dtFinal
                    where b.CODCOLIGADA == codcoligada
                    select b).ToList();

对于我使用的情况,视图返回441结果。 我需要将它们命名为CSTPIS列,它可以有三个不同的值(字符串):01,06或08。

我期待的结果是:

  • 01 =&gt; 170结果;
  • 06 =&gt; 143结果;
  • 08 =&gt; 128结果;

分组后的结果计数:

  • 01 =&gt; 170结果;
  • 06 =&gt; 172结果;
  • 08 =&gt; 109结果;

这是我的小组查询:

b.LinhasF500 = (from d in grupo
                                group d by d.CSTPIS into g
                                select new F500()
                                {
                                    VL_REC_CAIXA = g.Sum(f => f.VALOR.Value).ToString("F2"),

                                    CST_COFINS = g.FirstOrDefault().CSTCOFINS,
                                    VL_BC_COFINS = g.FirstOrDefault().CSTCOFINS == "08" ? null : g.Sum(f => f.VALOR.Value).ToString("F2"),
                                    ALIQ_COFINS = g.FirstOrDefault().CSTCOFINS == "08" ? null : g.FirstOrDefault().ALIQUOTACOFINS.Value.ToString("F2"),
                                    VL_COFINS = g.FirstOrDefault().CSTCOFINS == "08" ? null : g.Sum(f => f.COFINSBAIXA.Value).ToString("F2"),

                                    CST_PIS = g.FirstOrDefault().CSTPIS,
                                    ALIQ_PIS = g.FirstOrDefault().CSTPIS == "08" ? null : g.FirstOrDefault().ALIQUOTAPIS.Value.ToString("F2"),
                                    VL_PIS = g.FirstOrDefault().CSTPIS == "08" ? null : g.Sum(f => f.PISBAIXA.Value).ToString("F2"),
                                    VL_BC_PIS = g.FirstOrDefault().CSTPIS == "08" ? null : g.Sum(f => f.VALOR.Value).ToString("F2")
                                }).ToList();

为什么Linq会重复10个结果?

PS:直接在sql查询上分组正常工作

修改

在查看Ivan的评论后,我注意到以下内容:

EF使用三列来识别我的视图的复合键:IDLAN,CODCFO和CODCOLIGADA。

运行此查询后

select IDLAN, CODCFO, CODCOLIGADA, COUNT(IDLAN), COUNT(CODCFO), COUNT(CODCOLIGADA) from vw_SpedF500
where 0=0
    AND DATABAIXA BETWEEN '2015-08-01' AND '2015-08-31'
    and CODCOLIGADA = 7
GROUP BY IDLAN, CODCFO, CODCOLIGADA
HAVING COUNT(IDLAN) > 1 AND COUNT(CODCFO) > 1 AND COUNT(CODCOLIGADA) > 1
ORDER BY IDLAN

我得到124行,其中所有三个键都有多个寄存器。

我有什么方法可以在EF上完成这项工作吗?

修改

我再次重新检查了一切。第一个查询返回正确的结果,对象已经在内存中。

分组已在内存中的对象时,而不是在查询期间,会出现问题。它与EF无关。

我想我会将此更改为SqlCommand(会导致一个小的性能问题,因为我必须运行此查询三次,但是......)

1 个答案:

答案 0 :(得分:0)

看起来您的LINQ查询可能限制太多 - 这已经让我感到厌倦了几次。通过删除第二个where关键字并将最终语句与第一个关联结合使用限制较少的过滤器。

这样的东西可以给你你想要的东西:

var data = (from b in db.vw_SpedF500
            where b.DATABAIXA >= dtInicial &&
                  b.DATABAIXA <= dtFinal &&
                  b.CODCOLIGADA == codcoligada
            select b).ToList();

如果您尝试确保LINQ查询仅返回与此匹配的结果:

b.DATABAIXA >= dtInicial && b.DATABAIXA <= dtFinal

OR 这个(与相对)

b.CODCOLIGADA == codcoligada

你可以试试这个:

var data = (from b in db.vw_SpedF500
            where (b.DATABAIXA >= dtInicial &&
                   b.DATABAIXA <= dtFinal) ||
                   b.CODCOLIGADA == codcoligada
            select b).ToList();

我希望我明白这一点!