C# 在aspx代码隐藏中需要更好的性能
我编写了一个asp.net网站,用于创建包含指定项目的报告(转换为Excel)。我通过EF从SQL数据库获取这些项。该查询非常有效,需要大约2000个项目,大约1msC# 在aspx代码隐藏中需要更好的性能,c#,asp.net,sql-server,excel,datatable,C#,Asp.net,Sql Server,Excel,Datatable,我编写了一个asp.net网站,用于创建包含指定项目的报告(转换为Excel)。我通过EF从SQL数据库获取这些项。该查询非常有效,需要大约2000个项目,大约1ms var itemsToQuery = (from i in context.item where ...... ..... ..... orderby ....... select new { fields..... }); 现在对我来说很棘手。对于每个项目,我必须从数据库
var itemsToQuery = (from i in context.item
where ......
.....
.....
orderby .......
select new
{
fields.....
});
现在对我来说很棘手。对于每个项目,我必须从数据库中查询额外的数据(第一次查询没有机会获得这些数据)。我只使用一个数据库连接到安全时间(对于主查询和方法中的每个其他查询)。我想我的性能问题从这里开始。我有2000个项目,下面的循环如下所示:
foreach(var item in itemsToQuery)
{
another query;
another query;
another query;
etc.....
// at the end it looks like
datatable.add(item.name, item.number, item.stuff ......);
}
因此,我要为这2000项中的每一项做另外8个查询。这项工作大约需要5分钟(取决于项目数量)。之后,我需要这个数据表来填写我的Excel表格。这很好,“快”
你能给我一些专家建议如何使这个循环、查询或数据表的填充更有效吗
我考虑了一种多任务处理的解决方法,并创建了一个站点,您可以在其中查看excel的状态(通过ajax调用),完成后可以下载它。现在,我只是封锁了这个网站的用户界面,用户必须坐在屏幕前,直到它完成,没有任何信息,他必须等待多久。运行时钟的gif和js屏幕示例:
重要的一点是,我不能在数据库中创建视图或存储过程,因为我不允许这样做。我必须执行代码隐藏中的每个查询等
我知道这个程序是业余编写的,但这就是为什么我必须立即改变它
[编辑]
下面是我提到的示例查询!仅供参考——我并没有写下所有的查询。其中一些(如所有者
或每月工作时间
)来自外部资源
String changeDate = CalcÄnderungsDat(context
.ticket_history
.FirstOrDefault(x => x.history_type_id == 25 && x.ticket_id == item.ticketID).change_time.ToString());
String finishdate = CalcFinishDat((from tih in context.ticket_history
where (tih.name == "Reset of unlock time." && tih.ticket_id == item.ticketID)
|| (tih.state_id == 2 && tih.history_type_id == 1 && tih.ticket_id == item.ticketID)
select tih.change_time).Max().ToString());
try
{
string owner= (from a in context.article
where
item.ticketID == a.ticket_id &&
a.id ==
(from art in context.article
where art.a_subject.Contains("esitzer")
&& art.ticket.id == item.ticketID
&& art.ticket_id == art.ticket.id
select new { art.id }).Max(p => p.id)
select new { a.a_from }).FirstOrDefault().a_from;
}
catch (Exception)
{
string owner = (from a in context.article
where a.ticket.id == item.ticketID && a.ticket_id == a.ticket.id &&
a.id ==
(from art in context.article
where art.ticket.id == item.ticketID
&& art.ticket_id == art.ticket.id
select new { art.id }).Min(p => p.id)
select new { a.a_from }).FirstOrDefault().a_from;
}
decimal? monatszeit = (from ta in context.time_accounting
where
ta.change_time >= startdat &&
ta.change_time <= enddat &&
ta.ticket_id == item.ticketID
group new { ta } by new
{
ta.ticket_id,
ta.ticket.id,
ta.ticket.tn
} into g
select new
{
Zeiteinheit = (Decimal?)g.Sum(p => p.ta.time_unit),
}).SingleOrDefault().Zeiteinheit;
String changeDate=CalcÄnderungsDat(上下文)
.历史
.FirstOrDefault(x=>x.history\u type\u id==25&&x.ticket\u id==item.ticketID).change\u time.ToString();
字符串finishdate=CalcFinishDat((来自context.ticket\u历史中的tih
其中(tih.name==“重置解锁时间”。&&tih.ticket\u id==item.ticketID)
||(tih.state\u id==2&&tih.history\u type\u id==1&&tih.ticket\u id==item.ticketID)
选择tih.change_time).Max().ToString();
尝试
{
字符串所有者=(来自context.article中的
哪里
item.ticketID==a.ticket\u id&&
a、 身份证==
(来自上下文中的艺术)
艺术a_主题包含(“esitzer”)
&&art.ticket.id==item.ticketID
&&art.ticket_id==art.ticket.id
选择new{art.id}).Max(p=>p.id)
选择新的{a.a_from}).FirstOrDefault().a_from;
}
捕获(例外)
{
字符串所有者=(来自context.article中的
其中a.ticket.id==item.ticketID&&a.ticket\u id==a.ticket.id&&
a、 身份证==
(来自上下文中的艺术)
其中art.ticket.id==item.ticketID
&&art.ticket_id==art.ticket.id
选择new{art.id}).Min(p=>p.id)
选择新的{a.a_from}).FirstOrDefault().a_from;
}
十进制的monatszeit=(来自context.time\u accounting中的ta)
哪里
ta.change_time>=起始时间&&
ta.变更时间p.ta.时间单位),
}).SingleOrDefault().Zeiteinheit;
等等。总的来说,有7个查询和1个外部方法用于计算主查询中每个项目的特殊日期(此方法不应该是问题)。如何将它们放入一个完整的查询中?这会提高我的表现吗
[编辑-另一次尝试!]
你觉得这个流程图怎么样?
- 客户端向服务器发送请求,服务器将条目写入 数据库中的“作业”表
- 发送请求后,客户机从DB获取作业ID 立刻
- 有了这个ID,客户端可以对进度(状态)进行AJAX调用
- Web服务每秒都在检查是否有新的作业 数据库中的状态-1
- 为状态为-1的每个作业创建一个新任务
- 在此任务中,将使用ReportMaker.GenerateReport(idAUFTRAG)方法 叫
- ReportMaker有一个事件ReportProgress
- 调用方(任务)订阅此事件并将每个更改写入 数据库
- 数据库访问器->任务
- 客户端执行Ajax回调
这肯定会提高性能!!!对于这样一个小项目来说,这听起来是不是太多的工作了?您可以考虑为已经检索到的数据创建一个缓存解决方案。因此,查询结果将存储在内存中,并且不会每次都检索,因此性能将大大提高
您必须考虑刷新缓存的频率。另一个选项是检查是否出现一些新数据,并进行只检索最新数据的查询。还有哪些查询?为什么您必须为每个项目执行这些操作,而不是创建关系并在单个查询中加载所有内容,例如使用
Include
子句?鉴于每个后续查询从非关系表中获取单个数据
,这不意味着确实存在关系吗?是的,这就是我的意思,它们是相关的,它只是没有写入数据库约束。如果它们可以由一个公共字段关联,那么在一个查询中就很可能得到您想要的一切。但这里有另一种方法:你说你不能创建视图或过程,但是索引呢?查看“主”查询和“从属”查询的执行计划,查找诸如索引扫描等浪费的部分,并尝试用索引搜索的适当索引用法替换它们