C# 代码性能-来自两个不同数据库的数据填充视图

C# 代码性能-来自两个不同数据库的数据填充视图,c#,asp.net-mvc,performance,entity-framework,C#,Asp.net Mvc,Performance,Entity Framework,基本上,我有一个MVC站点,其中存储联系人,以及各种信息,如姓名、公司等,当他们在某处签入时,这些联系人对不同地点的访问也会记录在一个单独的数据库中 因此,联系人和访问被保存在单独的数据库中 我的MVC站点中有一个选项卡,显示用户联系人的个人资料,当在某个位置检测到他们的存在时,该个人资料会上升到列表的顶部 我已经建立了这个,它的工作绝对好。但是,对于大量联系人,页面需要很长时间才能填充,直到超时。这就是我的过程 首先,我获取所有当前用户联系人,并根据数据创建视图模型列表: var model

基本上,我有一个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();
正如您在上次访问中所看到的,我调用了一个名为
findLastVisit()
的方法:

公众访问FindLastVisite(联系方式)
{
var date=DateTime.Now;
var item=inboundContext.visions。
其中(d=>LocIds.Contains(d.LocationId)&&
d、 ContactId==contact.Id&&
d、 合同日期(d.合同日期)
.FirstOrDefault();
如果(项!=null)
{
退货项目;
}
else{返回新访问{};}
}
然后在视图中,我为每个配置文件显示这些信息,基本上是在一个列表中。因此,在加载页面时,整个列表应首先填充页面

因此,我需要的基本功能流程是:

  • 从context1获取所有用户联系人
  • 使用context2中该联系人上次记录的访问创建视图模型
我已经测试过,问题是列表中的每个联系人都会调用一次
findLastVisit()
方法。这是一个为每个联系人获取最后一次访问的过程,当数量过大时,需要花费很长时间才能完成。这是非常低效的…如果我忽略了上次访问的数据,那么它加载得非常快

只是想知道是否有人能找到一种更省时的方法,或者我是否需要研究其他选项,比如在没有上次访问信息的情况下渲染视图,以及用户通过单击他们的个人资料来显示这些信息


JK

可能大多数解决方案都会将这些查询分开,并在其中创建一个部分,以便查询每个数据库一次,并且两个数据库都有ClientId列。然后,您可以加入ContactId列中的这些列,以获得最终结果

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

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

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

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

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


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

解决这一问题的大多数解决方案可能包括将这些查询分开,并制作WHERE-part,以便查询每个数据库一次,并且两个数据库都有ClientId列。然后,您可以加入ContactId列中的这些列,以获得最终结果

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

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

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

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

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


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

是的,我的测试是针对大约1000个联系人的,只是想看看我能以多快的速度获得它,然后再决定简化视图。谢谢你的回复。我还认为我应该改变我的第二个查询,只包括使用Distinct和ContactId分组的最后一次访问…我现在就开始吧是的,我的测试是针对大约1000个联系人的,只是想看看我能以多快的速度得到它,然后再决定简化视图。谢谢你的回复。我还认为我应该改变我的第二个查询,只包括使用Distinct和ContactId分组的最后访问…我现在就开始
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 { }; }

    }