2011-04-01 21 views
2

我想优化我的应用程序,我注意到一个查询被触发多次没有任何明显的原因。Linq查询被触发多次没有任何明显的原因

是一个MVC 3应用程序,剃须刀,我使用Linq和EF。

我有ViewModel类与几个属性。 其中一个属性是用于查看的模型。

这是我的控制器(我忽略所有其他属性初始化):

public ActionResult companyDetail(Guid id) 
    { 
     companyDetailsViewModel myModel = new companyDetailsViewModel(); 
     myModel.companyDetail = companiesRepository.getCompany(id); 
     return View(myModel); 
    } 

这是我getCompany方法:

public company getCompany(Guid id) 
    { 
     return db.companies.Single(c => c.id == id); 

    } 

的看法是太长粘贴这里,但是是一个简单的看法。 例如,这是一个部分:

<div id="companyName"> 
<h2> 
    @Model.companyDetail.companyName 
</h2> 
</div> 
<div id="companyInfoWapper"> 
    <div class="companyInfo"> 
    <h5> 
    industry: @Model.companyDetail.industry<br /> 
    revenue: @String.Format("{0:C}", Model.companyDetail.revenue) 
     </h5>   
    </div> 
</div> 

我使用AnjLab SQL事件探查器来查看交易..

  • 当我打电话的观点,这是 叫3次查询。
  • 生成的SQL是 所有3
  • 交易代码是不同的完全相同的,并且也 时间变化一点点。
  • 其余的都差不多。

任何想法什么可以使这个查询多次运行?

另一个问题!

任何人都知道为什么db.companies.Single(c => c.id == id)请求顶部2?像这样:

SELECT TOP(2) [Extent1]。[id] AS [id],...。

在此先感谢!

埃德加。

更新!

第三个电话是我的错,我修好了。 但是,我觉得这个:

该应用程序是多语言,所以我写了一个实现控制器的类。

我把这个问题跟踪到这个类。查询在课程结束时第二次触发,当我打电话给基地时:

base.Execute(requestContext); 

当然,再次调用操作。

任何想法如何防止这种情况?

另一个更新!

Linkgoron问为什么我调用Base.Execute(),答案是因为localizedController的实现。

但他的问题让我觉得,有代码的另一部分:

public abstract class LocalizedControllerBase : Controller 
{  

public String LanguageCode { get; private set; } 

private String defaultLanguage = "es"; 
private String supportedLanguages = "en|es|pt"; 

protected override void Execute(RequestContext requestContext) 
{ 
    if (requestContext.RouteData.Values["languageCode"] != null) 
    { 
     LanguageCode = requestContext.RouteData.Values["languageCode"].ToString().ToLower(); 

     if (!supportedLanguages.ToLower().Contains(LanguageCode)) 
     { 
      LanguageCode = defaultLanguage; 
     } 


    } 
    else { 
     LanguageCode = defaultLanguage; 
    } 

    System.Globalization.CultureInfo culture = System.Globalization.CultureInfo.CreateSpecificCulture(LanguageCode); 

    Thread.CurrentThread.CurrentCulture = culture; 
    Thread.CurrentThread.CurrentUICulture = culture; 

    base.Execute(requestContext); 
} 
} 

我控制器这样的定义:

public class companiesController : LocalizedControllerBase 

我把一个破发点中“基地。执行“和另一个在”返回查看(myModel)“在控制器中。

当我调用视图companyDetail时,第一站是在base.Execute中,第二站是在返回视图中,但由于某种原因,第三站在Base.Execute中,第四站在Return View中,最后是视图呈现。

这让我疯狂!

+0

您是否曾尝试在调试器中逐步运行并查看执行查询的位置? – Linkgoron 2011-04-01 01:09:53

+0

检查您的操作方法是否仅在浏览器读取周期中被调用一次。错误的HTML可能导致重复执行操作方法。我已经看到格式不正确的图像标签导致此类问题。 – 2011-04-01 06:06:35

+0

你为什么要调用base execute? – Linkgoron 2011-04-01 17:27:06

回答

6

任何人都知道为什么db.companies.Single(c => c.id == id)请求top 2?像这样:

SELECT TOP(2)[Extent1]。[id] AS [id], ...。

Single()抛出一个异常,如果不是正好有一个匹配 - 因此LINQ到实体提供商转变,作为一个top 2查询是足够的数据来做出决定 - 如果查询返回2个结果还是没有抛出异常,否则返回唯一的结果。

+0

谢谢!我不知道我是如何错过的! – epaulk 2011-04-01 02:32:46

1

这没有意义。如果多次执行查询,您必须多次调用GetCompany方法。一旦你调用Single查询被执行并且Company实例被实现,所以在视图中多次使用它将不会导致新的执行。那些另外的调用必须由你的代码的不同部分引起。

Btw。您可以使用Find(在EF 4.1中)或GetObjectByKey(在EFv1和EFv4中)而不是Single来避免它们。如果用相同的实体键的实体已经载入Single始终执行数据库而Find首先检查查询,但不执行数据库查询返回的实例:

这是的DbContext API代码(EF 4.1):

public company getCompany(Guid id) 
{ 
    // Id must be primary key 
    return db.companies.Find(id); 
} 

ObjectContext API的代码有点复杂,因为您首先必须构建需要实体集名称的EntityKeyHere我描述了完整的例子,它适用于不同的键类型和名称。

相关问题