KADEM Mohammed
KADEM Mohammed

Reputation: 1650

Is it the correct way to use entity framework?

Im Beginner and i wanted to know if what i am doing is right, cause i've being queering a single table of 350 records and it took almost a minute to display ! i think I'm doing something wrong. So this is how i am doing it :

CODE INSIDE THE CLASS : SPOT

    /// <summary>
    /// Return The City Of this Spot
    /// </summary>
    /// <returns>City Of The Spot</returns>
    public City GetCityOfThisSpot()
    {
        City value;
        using (var ctx = new GhanDBEntities())
        {
            var firstOrDefault = ctx.Spots.FirstOrDefault(s => s.IdSpot == IdSpot);
            var city = firstOrDefault.City;
            value = city;
        }
        return value;
    }

and then in my winform i use something life this :

CODE IN THE WINFORM :

List<City> listOfCities = new List<City>();
        foreach (var spot in listOfspot)
        {
            listOfCities.Add(spot.GetCityOfThisSpot);
        }

I think i shouldn't do it this way, because foreach Spot i am creating a context and destroying it !? can you correct me please.

Upvotes: 0

Views: 311

Answers (3)

Uriil
Uriil

Reputation: 12628

I can give you few suggestions:

  1. you are using FirstOrDefault, but not checking for null, i think it would be better to use Find, Single or First, or add null(you won't get any speed benefits from this)

  2. most likely you will get speed benefits from batch request:

    var ids = listOfspot.Select(p => p.IdSpot).ToList();
    var listOfCities = ctx.Spots.Where(p => ids.Contains(p.IdSpot))
                          .Select(p => p.City).ToList();
    

Upvotes: 3

Sergey Berezovskiy
Sergey Berezovskiy

Reputation: 236318

DbContext is a light-weight class which is not a problem to create for each query. But with WinForms application thats just an overkill - you can reuse same instance of context during whole application lifetime. Note - for web applications you usually create instance of context which is reused for all queries during same request.

So, you don't need to dispose context in WinForms application. What you really need here is navigation property for City in your Spot entity:

public virtual City City { get; set; }

In this case Entity Framework will lazy-load city when you will need it (remember - keep context not disposed). Also if you want to get cities of many spots, then just do eager-loading of cities when you are loading spots:

var spots =  ctx.Spots.Include(s => s.City);

In this case Entity Framework will join both tables and return spots with already loaded cities.

In both cases getting cities of spots will look like:

List<City> listOfCities = listOfspot.Select(s => s.City).ToList();

I also suggest you to read Jon Gallant article Do I always have to call Dispose() on my DbContext objects? There you can find Diego Vega (the Senior SDE Lead on Entity Framework) response, which states that in common scenarios (if you don't open database connection manually) you don't need to call Dispose on DbContext.

Upvotes: 1

road242
road242

Reputation: 2532

DbContext isn't the problem in this case.

GetCityOfThisSpot()

is making a db-query, the code in the winform is running the query 350 times...

Make a join to make this much faster.

Upvotes: 1

Related Questions