这是使用实体框架的正确方法吗?

时间:2014-02-22 10:24:06

标签: c# entity-framework lifetime

我是初学者,我想知道我在做什么是正确的,因为我正在排队一个包含350个记录的表,并且花了差不多一分钟才显示出来!我想我做错了什么。 所以我就这样做了:

课程内的代码: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;
    }

然后在我的winform中使用了一些生命:

WINFORM中的代码:

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

我想我不应该这样做,因为foreach Spot我正在创建一个上下文并摧毁它!你能纠正我吗。

3 个答案:

答案 0 :(得分:3)

我可以给你一些建议:

  1. 您正在使用FirstOrDefault,但没有检查null,我认为最好使用Find,Single或First,或者添加null(您将无法获得任何速度受益于此)

  2. 您很可能会从批量请求中获得速度优势:

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

答案 1 :(得分:1)

DbContext是一个轻量级类,对于每个查询都不是一个问题。但是使用WinForms应用程序只是一种过度杀伤 - 您可以在整个应用程序生命周期中重用相同的上下文实例。注 - 对于Web应用程序,您通常会创建上下文实例,在同一请求期间重用所有查询。

因此,您不需要在WinForms应用程序中配置上下文。这里你真正需要的是你的Spot实体中的城市navigation property

public virtual City City { get; set; }

在这种情况下,实体框架将lazy-load城市当你需要它时(记住 - 不保留上下文)。此外,如果您想要获得许多景点的城市,那么当您加载景点时,只需要eager-loading个城市:

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

在这种情况下,实体框架将连接两个表并返回已加载城市的点。

在这两种情况下,获得景点的城市将如下:

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

我还建议你阅读Jon Gallant的文章Do I always have to call Dispose() on my DbContext objects?在那里你可以找到Diego Vega(实体框架的高级SDE主管)回复,其中说明在常见的情况下(如果你不手动打开数据库连接) )你不需要在DbContext上调用Dispose。

答案 2 :(得分:1)

在这种情况下,DbContext不是问题。

GetCityOfThisSpot()

正在进行数据库查询,winform中的代码运行查询350次...

进行联接以加快速度。