我可以以某种方式改进这个 linq 查询吗?

Posted

技术标签:

【中文标题】我可以以某种方式改进这个 linq 查询吗?【英文标题】:Can I improve this linq query somehow? 【发布时间】:2014-03-11 12:30:03 【问题描述】:

我写了以下 linq 查询:

using (var db = new CardContext())

    var result = (from c in db.Creatures
                  orderby c.Name
                  select new CardDisplay()
                      
                          ImgPath = c.Image,
                          CardType = c.CardType.Name,
                          Name = c.Name
                      ).ToList();

    result.AddRange(from f in db.Fortunes 
                    orderby f.Name
                    select new CardDisplay()
                        
                           ImgPath = f.Image,
                           CardType = f.CardType.Name,
                           Name = f.Name
                        );

    return View(result);

这里是表格:

我能否以某种方式改进我的查询,使其出现在 1 个查询中,而不是两个。正如您在表格图中看到的那样,我有更多实体来提取所需的数据(总共 5 个,其余未显示),因此会有更多查询。或者可能是我,我做得对吗?还有一个问题,一般来说写 1 个复杂的 linq 查询还是写几个简单的查询更好?

Union 的解决方案非常好,谢谢大家。但我希望带接口的 Jonny Piazzi 解决方案能够工作,也许我做错了什么。

【问题讨论】:

您是否使用过 Code First 和/或 POCO? 代码优先[要求的帖子长度] 这样你就可以使用Interface了。 结果列表是否有可能包含重复条目?你需要/关心他们吗? 结果中没有重复项。界面,听起来很有趣,有没有关于这个的文章? 【参考方案1】:

你应该可以使用联合:

var result = (from c in db.Creatures
              orderby c.Name
              select new CardDisplay()
                  
                      ImgPath = c.Image,
                      CardType = c.CardType.Name,
                      Name = c.Name
                  ).Union(
                from f in db.Fortunes 
                orderby f.Name
                select new CardDisplay()
                    
                       ImgPath = f.Image,
                       CardType = f.CardType.Name,
                       Name = f.Name
                    ).ToList()

使用这个单一查询,只会向数据库发出一个请求,而不是两个。

参考:http://code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b

【讨论】:

【参考方案2】:

您无需将第一个结果转换为列表。 使用 Union LINQ 运算符

var resultFromCreatures = (from c in db.Creatures
              orderby c.Name
              select new CardDisplay()
                  
                      ImgPath = c.Image,
                      CardType = c.CardType.Name,
                      Name = c.Name
                  );

var resultFromFortunes = (from f in db.Fortunes 
                orderby f.Name
                select new CardDisplay()
                    
                       ImgPath = f.Image,
                       CardType = f.CardType.Name,
                       Name = f.Name
                    );

var result = resultFromCreatures.Union(resultFromFortunes);

【讨论】:

请注意 OP,由于延迟执行,这也将是对数据库的单个请求。【参考方案3】:

如果您使用 Code First,您可以使用界面,如下所示:

// The Interface
public class Fortune : ICardDisplay

    public string Image  get; set; 

    public CardType CardType  get; set; 

    public string Name  get; set; 

在你的类中实现一个接口:

public class Creature : ICardDisplay  /* ... */ 

public class Fortune : ICardDisplay  /* ... */ 

现在您可以执行如下查询:

var result = (
    from c in db.Creatures.Cast<ICardDisplay>().Union(db.Fortune)
    orderby c.Name
    select new CardDisplay()
        
            ImgPath = c.Image,
            CardType = c.CardType.Name,
            Name = c.Name
        ).ToList();

【讨论】:

它说:LINQ to Entities 只支持转换 EDM 原语或枚举类型 :(

以上是关于我可以以某种方式改进这个 linq 查询吗?的主要内容,如果未能解决你的问题,请参考以下文章

LINQ 分组查询

如何改进此 LINQ 查询以查找用户将列表中的所有技能

在linq查询中以匿名类型设置动态对象的所有属性

有没有办法改进这个查询

这个 Linq 查询可以输入为“var”以外的任何内容吗?

使用 EF6 优化 LINQ 查询