总结:
我们有两个相同的数据库,一个在本地服务器上,一个在 Azure 上。
我们有一个 C# 系统来访问这些数据库,调用存储过程。
当从 C# 系统调用到 Azure 数据库时,存储过程的运行非常非常缓慢。它们从 C# 到本地服务器,以及从 SSMS 到 Azure 和本地数据库都运行良好。
例如,调用存储过程“usp_DevelopmentSearch_Select”
本地数据库,SSMS:1 秒
本地数据库,C#:1 秒
Azure 数据库,SSMS:1 秒
Azure 数据库,C#:17 分钟
这发生在多个存储过程上,我只是以 usp_DevelopmentSearch_Select 为例,来测试解决方案并跟踪执行计划。
我已经排除了 ARITHABORT(通常的嫌疑人),似乎在 SSMS 和 C# 系统中运行 usp_DevelopmentSearch_Select 会生成功能相同的执行计划。
详情:
我们编写了一个非常大的 C# 系统,它访问 SQL Server 数据库。
目前,我们所有的客户都在自己的服务器上本地托管自己的数据库,但是我们正在研究在 Azure 上托管数据库的选项。因此,我建立了一些小型 Azure 测试数据库,解决了这些问题,并启动了一个 Azure 托管系统。
然后我复制了我们客户的一个数据库,以比较本地托管与 Azure 上托管的性能。
实际的客户端数据库在 Azure 上表现得非常糟糕!
第一个屏幕调用存储过程“usp_DevelopmentSearch_Select”
连接到他们服务器上的数据库:-
在 SSMS 中,调用存储过程(如下)大约 1 秒返回值
EXEC usp_DevelopmentSearch_Select @MaxRecord = 100, @SearchType = 'CUR'
Run Code Online (Sandbox Code Playgroud)
在我们的 C# …
我有一个继承的实体框架查询,其中包括几个总和,缩减示例:-
from c in db.Clients
where {where clauses}
select new
{
ClientID = c.ClientID,
ClientName = c.ClientName,
CurrentBalance = c.ClientTransactions.Select(ct => ct.Amount)
.DefaultIfEmpty(0m).Sum(),
}).ToList();
Run Code Online (Sandbox Code Playgroud)
随着客户端数量和交易数量的增长,这个查询显然变得越来越慢。
理想情况下,我希望存储余额而不是每次都计算它们,但目前系统不这样做,而且实施起来将是一个非常大的变化,所以现在我只是尝试创可贴修复。
我试图实施的解决方法是不为那些对它们不感兴趣的人做总和计算(有几个,上面的例子只有一个)。
我的第一次尝试只是使用三元条件运算符来确定是否进行计算:-
from c in db.Clients
where {where clauses}
select new
{
ClientID = c.ClientID,
ClientName = c.ClientName,
CurrentBalance = ClientSearchExcludeCurrentBalance ? 0m :
c.ClientTransactions.Select(ct => ct.fAmount).DefaultIfEmpty(0m).Sum(),
}).ToList();
Run Code Online (Sandbox Code Playgroud)
事实证明,这样做的问题在于,无论条件 (ClientSearchExcludeCurrentBalance) 的值如何,仍然会计算双方,然后由三元决定使用哪一个。因此,即使将条件设置为 false,总和仍会得到处理,并且查询时间太长。
注释掉总和,如下...
from c in db.Clients
where {where clauses}
select new
{
ClientID = c.ClientID,
ClientName = c.ClientName,
CurrentBalance = ClientSearchExcludeCurrentBalance ? 0m …Run Code Online (Sandbox Code Playgroud) 我有一个用 C# 编写的 Windows 服务,它轮询 Exchange 服务器来处理发送到无人值守电子邮件箱的邮件。
它一直工作正常,直到今天它抛出以下错误:-
EXCEPTION: Microsoft.Exchange.WebServices.Data.ServiceVersionException: The property Hashtags is valid only for Exchange Exchange2015 or later versions.
at Microsoft.Exchange.WebServices.Data.PropertyBag.set_Item(PropertyDefinition propertyDefinition, Object value)
at Microsoft.Exchange.WebServices.Data.ComplexPropertyDefinitionBase.InternalLoadFromXml(EwsServiceXmlReader reader, PropertyBag propertyBag)
at Microsoft.Exchange.WebServices.Data.ComplexPropertyDefinitionBase.LoadPropertyValueFromXml(EwsServiceXmlReader reader, PropertyBag propertyBag)
at Microsoft.Exchange.WebServices.Data.PropertyBag.LoadFromXml(EwsServiceXmlReader reader, Boolean clear, PropertySet requestedPropertySet, Boolean onlySummaryPropertiesRequested)
at Microsoft.Exchange.WebServices.Data.ServiceObject.LoadFromXml(EwsServiceXmlReader reader, Boolean clearPropertyBag, PropertySet requestedPropertySet, Boolean summaryPropertiesOnly)
at Microsoft.Exchange.WebServices.Data.EwsServiceXmlReader.ReadServiceObjectsCollectionFromXml[TServiceObject](XmlNamespace collectionXmlNamespace, String collectionXmlElementName, GetObjectInstanceDelegate`1 getObjectInstanceDelegate, Boolean clearPropertyBag, PropertySet requestedPropertySet, Boolean summaryPropertiesOnly)
at Microsoft.Exchange.WebServices.Data.EwsServiceXmlReader.ReadServiceObjectsCollectionFromXml[TServiceObject](String collectionXmlElementName, GetObjectInstanceDelegate`1 getObjectInstanceDelegate, Boolean clearPropertyBag, PropertySet requestedPropertySet, Boolean summaryPropertiesOnly)
at …Run Code Online (Sandbox Code Playgroud) 有人有任何 C# 代码可以接受从 Outlook 拖放到在.Net Framework 4.5或更高版本下工作的 Winforms 应用程序吗?
我有一些代码已经使用了大约 12 年,其中包括拖放项目的功能,包括来自 Outlook 的电子邮件。
当将目标框架设置为.Net Framework 4进行编译时,代码可以完美运行,但是我一直在开发的一些新功能需要.Net Framework 4.5或更高版本。但是,这会阻止从 Outlook 进行拖放操作。
代码非常复杂,它做了很多与问题无关的事情来确定文件的去向,以及它为谁显示等,所以我不会包括所有这些,但它中断的点很好并且简单的...
public string ImportEmail(DragEventArgs e)
{
string strResult = string.Empty;
var dataObject = new OutlookDataObject(e.Data);
var filenames = (string[]) dataObject.GetData("FileGroupDescriptor");
Run Code Online (Sandbox Code Playgroud)
在.NET 4下,上面的最后一行按预期返回文件名。
在.NET 4.5 或更高版本中,上面的最后一行返回null。
我在.NET 4.5、4.5.1、4.5.2、4.6、4.6.1、4.6.2和4.7.2(我安装的所有版本)下测试了它,它不适用于其中任何一个。
我已经花了几天时间尝试所有我能找到的拖放代码,但似乎都无法在 .Net 4.5 或更高版本下工作。
下面是我所做的测试表单的完整代码,使用了我从这里和其他地方挖掘的代码。无论您从 Outlook 拖放文件还是电子邮件,此代码都可以在 .Net Framework 4 下完美运行,但在 .Net Framework 4.5 或更高版本下都不起作用(再次测试所有相同版本)。
using System;
using System.IO;
using System.Collections.Generic; …Run Code Online (Sandbox Code Playgroud)