如何Linq-ify这个查询?

时间:2012-03-14 07:41:31

标签: c# linq select

我目前有这个Linq查询:

   return this.Context.StockTakeFacts
                .OrderByDescending(stf => stf.StockTakeId)
                .Where(stf => stf.FactKindId == ((int)kind))
                .Take(topCount)
                .ToList<IStockTakeFact>();

目的是返回StockCakes的topCount的每个事实,但我可以看到我只会获得topCount数量的事实。

我如何Linq-ify这个查询来实现我的目标?

我可以使用2个查询来获得top-topCount StockTakeId然后执行“之间”但我想知道Linq可能有什么技巧。

这就是我想要击败的。请注意,它更多的是学习无法找到解决方案。同样关注性能不是为了这些查询,但总的来说,我不想只是简单的东西,并发现它在幕后捶打。就像我在下面的第二个查询中包含句子的惩罚一样?

List<long> stids = this.Context.StockTakes
                .OrderByDescending(st => st.StockTakeId)
                .Take(topCount)
                .Select(st => st.StockTakeId)
                .ToList<long>();

            return this.Context.StockTakeFacts
                .Where(stf => (stf.FactKindId == ((int)kind)) && (stids.Contains(stf.StockTakeId)))
                .ToList<IStockTakeFact>();

3 个答案:

答案 0 :(得分:0)

这个怎么样?

 return this.Context.StockTakeFacts
                .OrderByDescending(stf => stf.StockTakeId)
                .Where(stf => stf.FactKindId == ((int)kind))
                .Take(topCount)
                .Select(stf=>stf.Fact)
                .ToList();

答案 1 :(得分:0)

如果我已经理解了你正确的事情,那该怎么样:

return this.Context.StockTakes
    .OrderByDescending(st => st.StockTakeId)
    .Take(topCount)
    .Join(
        this.Context.StockTakeFacts,
        st => st.StockTakeId,
        stf => stf.StockTakeId,
        (st, stf) => stf)
    .OrderByDescending(stf => stf.StockTakeId)
    .ToList<IStockTakeFact>();

答案 2 :(得分:0)

这是我尝试使用大多数查询语法并使用两个单独的查询:

var stids =
     from st in this.Context.StockTakes
     orderby st.StockTakeId descending
     select st.StockTakeId;

var topFacts =
    from stid in stids.Take(topCount)
    join stf in this.Context.StockTakeFacts
    on stid equals stf.StockTakeId
    where stf.FactKindId == (int)kind
    select stf;

 return topFacts.ToList<IStockTakeFact>();

正如其他人所说,你所寻找的是一个加入。因为连接扩展具有如此多的参数,所以它们可能有点令人困惑 - 所以我更喜欢在进行连接时查询语法 - 例如,如果您的订单出错,编译器会给出错误。到目前为止,Join更适合于过滤器,不仅因为它说明了数据如何连接在一起,而且还出于性能原因,因为它在数据库中使用时使用索引,而在linq中使用哈希时则使用哈希值。

您应该注意,我在第二个查询中调用Take来限制第二个查询中使用的topCount点数。我可以在into查询的选择行上使用stids(即查询延续)来组合两个查询,而不是有两个查询,但这会造成限制它的混乱到topCount个项目。另一种选择是将stids查询放在括号中并在其上调用Take。相反,将它分成两个查询似乎对我来说最干净。

每当我认为编译器可以推断出类型时,我通常会避免指定泛型类型;但是,IStockTakeFact几乎可以肯定是一个接口,无论具体类型如何实现它都可能由this.Context.StockTakeFacts;包含,这就需要在ToList调用中指定泛型类型。通常我省略了我的ToList调用的泛型类型参数 - 这似乎是我个人品味的一个元素,你的可能会有所不同。如果this.Context.StockTakeFacts已经是List<IStockTakeFact>,您可以安全地省略ToList来电中的通用类型。