【问题标题】:Code Performance - Data from two different databases populating view代码性能 - 来自两个不同数据库的数据填充视图
【发布时间】:2015-07-29 12:03:51
【问题描述】:

基本上,我有一个 MVC 站点,其中存储联系人,包括姓名、公司等各种信息,当他们在某个地方签到时,这些联系人对不同位置的访问也会记录在单独的数据库中。

所以联系人和访问保存在不同的数据库中。

我的 MVC 站点中有一个选项卡,它显示用户联系人的个人资料,并且在个人资料上升到列表顶部的位置检测到他们的存在。

我已经构建了它,它工作得非常好。但是,对于大量联系人,该页面需要很长时间才能填充它超时。所以这就是我的流程。

首先,我获取所有当前用户的联系人并根据数据创建视图模型列表:

var model = DbContext.Contacts.Where(x => x.Organisation.Id == org.Id).ToList().Select(x => new AttendeeViewModel
        {
            Id = x.Id,
            LastName = x.LastName,
            FirstName = x.FirstName,
            Company = x.Company,
            Position = x.Position,
            DateJoined = x.DateJoined == Convert.ToDateTime("1900-01-01 00:00:00.000") ? DateTime.Now : x.DateJoined,
            lastVisit = findLastVisit(x)                
        }).ToList();

正如你在 lastVisit 中看到的,我调用了一个名为 findLastVisit() 的方法:

public Visit findLastVisit(Contact contact)
    {

        var date = DateTime.Now;

        var item = inboundContext.Visits.
                   Where(d => LocIds.Contains(d.LocationId) &&
                   d.ContactId == contact.Id &&
                   d.DateOfContact <= date)
                   .OrderByDescending(d => d.DateOfContact)
                   .FirstOrDefault();

        if (item != null)
        {
            return item;
        }
        else { return new Visit { }; }

    }

然后在视图中,我会为每个配置文件显示此信息,基本上是在一个列表中。因此,在加载页面时,整个列表应该最初填充页面。

所以我需要的基本功能流程是:

  • 从 context1 中获取所有用户联系人
  • 使用从上下文 2 中记录的该联系人的最后一次访问创建视图模型

我已经测试过,问题是findLastVisit() 方法为列表中的每个联系人调用一次。当数字变得太大时,这个为每个联系人获取最后一次访问的过程需要很长时间才能完成。这非常低效....如果我忽略 lastVisit 数据,那么它会很快加载。

只是想知道是否有人可以看到更省时的方式来执行此操作,或者我是否需要转而研究其他选项,例如在没有最后访问信息的情况下呈现视图,以及用户通过点击他们的个人资料来显示此信息。

JK

【问题讨论】:

    标签: c# asp.net-mvc performance entity-framework


    【解决方案1】:

    可能对此的大多数解决方案将涉及将这些查询分开并制作 WHERE 部分,以便您查询每个数据库一次并且都具有 ClientId 列。然后你可以加入那些有最终结果的 ContactId 列。

    这可以在各个级别上完成,但是您可以尝试的一个简单更改与您在第二个查询中的更改非常相似 - LocIds.Contains(..):

    1) 从 DbContext.Contacts 中选择到临时列表中,无需调用 findLastVisit(),

    2) 选择相关的 clientId-s 并将其传递给第二个查询

    3) 在 ID 列表中选择客户的所有上次访问日期,并在结果中包含 CLientID 列

    4) 将 ClientId 列上的第一个查询和第二个查询结果加入到您的模型中。

    注意:您没有提到“大量联系人页面”的意思,但我在这里假设这是一个网络意义上的“页面”,大约 10-100 行。

    【讨论】:

    • 是的,我的测试是针对大约 1000 个联系人,只是想看看我能多快得到它,然后再决定简化视图。谢谢回复。我还认为我应该将第二个查询更改为仅包含使用 Distinct 和按 ContactId 分组的最后一次访问...我现在就试一试
    猜你喜欢
    • 2020-10-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-16
    相关资源
    最近更新 更多