我是初学者,我想知道我在做什么是正确的,因为我正在排队一个包含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我正在创建一个上下文并摧毁它!你能纠正我吗。
答案 0 :(得分:3)
我可以给你一些建议:
您正在使用FirstOrDefault,但没有检查null
,我认为最好使用Find,Single或First,或者添加null
(您将无法获得任何速度受益于此)
您很可能会从批量请求中获得速度优势:
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次...
进行联接以加快速度。