Kmaczek
Kmaczek

Reputation: 648

Can I improve this linq query somehow?

I wrote following linq query:

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);
}

Here are tables:

enter image description here

Can I improve somehow my query so it would be in 1 query, not two. As u can see in table diagram I have even more entities to extract needed data(5 total, rest not shown), so there would be even more queries. Or may be I,m doing it right? And one more question, is it better in general to write 1 complex linq query or few simple?

Solution with Union is very nice, thank you all. But I wish Jonny Piazzi solution with interface would work, maybe I'm doing something wrong.

Upvotes: 0

Views: 125

Answers (3)

Jonny Piazzi
Jonny Piazzi

Reputation: 3784

If you using Code First you can use interface, like this:

// The Interface
public class Fortune : ICardDisplay
{
    public string Image { get; set; }

    public CardType CardType { get; set; }

    public string Name { get; set; }
}

Implements a interface in your classes:

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

And

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

Now you can do a query like this:

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();

Upvotes: 1

nlips
nlips

Reputation: 1288

You don't need to convert your first result to a list. Use the Union LINQ operator.

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);

Upvotes: 3

Mister Epic
Mister Epic

Reputation: 16733

You should be able to use a Union:

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()

With this single query, only one request to the db will be made, instead of two.

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

Upvotes: 3

Related Questions