Linq 查询在没有任何明显原因的情况下被多次触发

发布于 2024-10-29 01:59:27 字数 3089 浏览 2 评论 0原文

我正在尝试优化我的应用程序,我注意到一个查询在没有任何明显原因的情况下被多次触发。

是一个 MVC 3 应用程序、razor,我正在使用 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 Profiler 来查看事务。

  • 当我调用视图时,查询是 叫了3次。
  • 生成的 SQL 是 3 个完全相同。
  • 交易 ID 不同,而且 持续时间略有不同。
  • 其余的都差不多。

知道什么可以使这个查询运行多次吗?

另一个问题!

有人知道为什么 db.companies.Single(c => c.id == id) 要求前 2 个吗?像这样:

选择顶部(2) [范围 1].[id] AS [id],...。

提前致谢!

埃德加.

更新!

第三次调用是我的错,我已修复它。 但是,我发现:

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

我将问题追溯到这个类。当我调用 Base: 时,查询在课程结束时第二次触发,

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

我在“Base.Execute”中放置了一个断点,在“return”中放置了另一个断点在控制器中查看(myModel)”

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

这让我抓狂!

I’m trying to optimize my app, and I notice that one query is triggered multiple times without any apparent reason.

Is a MVC 3 App, razor and I’m using Linq and EF.

I have ViewModel class with a couple of properties.
One of these properties is the model for to view.

This is my controller (I omit all the others properties initialization):

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

This is my getCompany method:

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

    }

The view is too long to paste here, but is a simple view.
This is a part for example:

<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>

I’m using AnjLab SQL Profiler to view the transactions..

  • When I call the view, the query it’s
    called 3 times.
  • The Generated SQL is
    the exact same on all 3.
  • The transaction ID is different, and also
    the duration varies a little bit.
  • The rest are pretty much the same.

Any Idea what can be making this query to run multiple times?

Another Question!

Anyone know why db.companies.Single(c => c.id == id) ask for top 2? Like this:

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

Thanks in Advance!

Edgar.

Update!

The third call was my fault, and I fix it. However, I find this:

The application is Multi-language, so I write a class that implements Controller.

I trace the problem to this class. The query is triggered the second time at the end of the class when I call the Base:

base.Execute(requestContext);

and of course, the action is called again.

Any Idea how to prevent this?

Another Update!

Linkgoron ask why I call Base.Execute(), the answer is because of the localizedController implementation.

But his question make me think, and there is another part of the code:

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);
}
}

My controller are defined like this:

public class companiesController : LocalizedControllerBase

I put a break point in “Base.Execute” and another in the “return View(myModel)” in the controller.

When I call the view companyDetail, the first stop is in base.Execute, the second is in return view, but for some reason there is a third stop in Base.Execute and a fourth in Return View, and finally the view is render.

This is making me crazy!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

狼性发作 2024-11-05 01:59:28

有人知道为什么 db.companies.Single(c
=> c.id == id) 要求前 2 个?像这样:

选择顶部 (2) [范围 1].[id] AS [id],
....

如果没有完全匹配,Single() 会引发异常 - 因此 Linq to Entities 提供程序会将其转换为 top 2 查询,该查询有足够的数据来做出决定 -如果查询返回 2 个结果或没有结果,则抛出异常,否则返回唯一的结果。

Anyone know why db.companies.Single(c
=> c.id == id) ask for top 2? Like this:

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

Single() throws an exception if there is not exactly one match - so the Linq to Entities provider translates that as a top 2 query which is enough data to make a decision - throw an exception if the query returns 2 results or none, return the only result otherwise.

思念绕指尖 2024-11-05 01:59:28

这没有道理。如果多次执行查询,则必须多次调用 GetCompany 方法。一旦您调用 Single ,就会执行查询,并且 Company 实例会被具体化,因此在视图中多次使用它不会导致新的执行。这些其他调用必须是由代码的不同部分引起的。

顺便提一句。您可以通过使用 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 的代码有点复杂,因为您首先必须构建需要实体集名称的 EntityKey这里我描述了适用于不同的密钥类型和名称。

This doesn't make sense. If the query is executed multiple times you must call GetCompany method multiple times. Once you call Single the query is executed and Company instance is materialized so using it multiple times in view will not cause new executions. Those another calls must be caused by different part of your code.

Btw. you can avoid them by using Find (in EF 4.1) or GetObjectByKey (in EFv1 and EFv4) instead of Single. Single always executes query in database whereas Find first checks if the entity with the same entity key was already loaded and returns the instance without executing db query:

This is code for DbContext API (EF 4.1):

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

Code for ObjectContext API is little bit complicated because you first have to build EntityKey which requires entity set name. Here I described full example which works with different key types and names.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文