0

I'm new to MVC and databases, but I'm fairly certain the way that I'm getting data from the database is incredibly inefficient.

public class PokemonViewController : Controller
{
    private PokemonDayCareDBEntities1 db = new PokemonDayCareDBEntities1();

    [Authorize]
    public ActionResult Pokemon(int id)
    {
        var pkmn = db.PlayerPkmns.ToList();
        PlayerPkmn thispkmn = null;

        //get pokemon from database where id = id
        foreach (var item in pkmn)
        {
            if (item.Id == id)
            {
                thispkmn = item;
            }
        }

....

I have the unique ID of the Pokemon that resides in the PlayerPkmns table, but I'm looping through the entire table in order to find the matching ID.

Depending on how large the table, the time this takes to execute would increase.

I'm positive there's a better way - would anyone know if there is one (also, the syntax on how to use it)

Thanks!

5
  • 2
    You need to get familiar with Linq-to-Entities . btw the code you would need is db.PlayerPkmns.Where(x=>x.Id == id).FirstOrDefault(); Commented May 22, 2017 at 12:30
  • No need for the where - FirstOrDefault takes a predicate. Commented May 22, 2017 at 12:32
  • @Alex isn't that the same as using where I mean behind the scenes.. Commented May 22, 2017 at 12:34
  • Technically yes, but there .Where is superfluous Commented May 22, 2017 at 12:34
  • @Alex I see it as a better readability.. For newbies at least.. Commented May 22, 2017 at 12:36

4 Answers 4

7

SingleOrDefault is your friend here.

Change this:

var pkmn = db.PlayerPkmns.ToList();

To

var pkmn = db.PlayerPkmns.SingleOrDefault(x => x.Id == id);

This will translate (roughly) into the following SQL

SELECT TOP 1 * FROM PlayerPkmns WHERE ID = @id
Sign up to request clarification or add additional context in comments.

1 Comment

thank you! I know it was a basic question, but I wasn't sure about the syntax (i think it's called a lambda expression)? Thank you!
3

Most effecient way to retrieve an entity is to use the .Find() Where primaryKey is the Id you are passing in.

var PlayerPkmn= db.PlayerPkmns.Find(primaryKey)

Comments

1

As you are using Linq to Entities, you should be able to use the Where() in combination with FirstOrDefault() :

var pkmn = db.PlayerPkmns.Where(x=>x.Id  == id).FirstOrDefault();

The way you are doing right now will cause all the records to be brought in memory which is not what you want i believe, and it will be much performant than the way you are doing right now, as with the way you are doing, it will load all records in to the memory.

7 Comments

There's no need to use Where: you can also pass a predicate ti FirstOrDefault.
@CarlesCompany there are multiple ways for doing that, in both case sql will be generated similar i guess and from db side only 1 row will be returned
@EhsanSajjad is right... unless there is no improvements in any metrics I think all the ways are acceptable..
If you use resharper, this will show up as a warning. I like a green light on all my files :)
unfortunately i don't have resharper :/
|
-1

I suppose that PokemonDayCareDBEntities1 is an Entity Framework Data Context. In that case you can use db.PlayerPkmns.Find(id) or db.PlayerPkmns.SingleOrDefault(x => x.Id == id) if you want to handle the case where the entity does not exist in the DB, db.PlayerPkmns.Single(x => x.Id == id) if you are sure that there is strictly one element in the DB (will throw if the entity does not exist).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.