很抱歉,这个问题是否会泛泛,但是如果这是有关基于ASP.NET MVC 5 Owin的默认连接到MSSQL Server的基于Owin的应用程序的问题,我将不会遇到困难,但是我们将CRM用作数据库。
好的,正如我提到的,我正在研究ASP.NET MVC5应用程序,并且很难找到创建,保持打开和关闭与Dynamics CRM 365的连接的最佳实践的最佳方法是什么?
我发现了很多帖子和博客,但每个人都站在他的一边。
有人说,每个请求都最好在using
语句中打开新连接,这样就可以立即将其关闭(听起来不错,但请求速度可能很慢,因为在每个请求上都需要打开与CRM的新连接)。
有人说,最好在应用程序范围内创建singleton
对象,使其在应用程序生存期内保持打开状态,并在每次请求时重用它。
通常我会在一些简单的控制台应用程序中使用OrganizationServiceProxy
,但是在这种情况下,我不确定是否应该使用OrganizationServiceProxy
或CrmServiceClient
或其他名称?
如果有人遇到或遇到过类似的问题,那么任何提示都会很棒。
更新:
@Nicknow
我从SDK 365下载了SDK,并且正在使用此dll-s。Microsoft.Xrm.Sdk.dll
,Microsoft.Crm.Sdk.Proxy.dll
,Microsoft.Xrm.Tooling.Connector.dll
和Microsoft.IdentityModel.Clients.ActiveDirectory.dll
。
你提到
Microsoft.CrmSdk.XrmTooling.CoreAssembly 8.2.0.5。
如果这个nuget软件包使用我下载的官方程序集是正确的,或者对此软件包进行了一些修改?
关于那个测试
证明测试
如果我做对了,无论我使用using
语句,实现Dispose()
方法还是在应用程序范围内仅在应用程序范围内使用静态类,都将得到相同的实例(如果我使用默认设置RequireNewInstance=false
)?
为了简化代码,我通常创建一个静态类(也可以使用一个单例,但是通常会显得过大)以返回CrmServiceClient对象。这样,如果我想更改有关如何建立连接的任何内容,我的代码就不会被新的CrmServiceClient调用所困扰。
因此,在应用程序范围内创建寿命为应用程序生存期的静态类是一个好习惯吗?这意味着发出请求的每个用户都将使用相同的实例吗?那不是那个连接的性能问题吗?
您的所有方法调用都将执行完成或引发异常,因此即使GC花费了一段时间,那里也没有开放的连接会占用资源和/或阻止其他活动。
这使我回到本节,在那里我总是得到相同的CrmServiceClient
实例,并得到了xrm.tooling处理另一端的缓存连接的那部分,但是在这一方面会发生什么(Web应用程序)。
是不是与CRM(即CrmServiceClient
)非托管资源的连接,我是否应该对Dispose()
进行显式编码?
我发现了一些带有CrmServiceClient
的示例,并且几乎所有示例中的CrmServiceClient
都是使用IOrganizationService
或CrmServiceClient.OrganizationWebProxyClient
转换为CrmServiceClient.OrganizationServiceProxy
的。
为什么会这样?这样做有什么好处?
我有很多问题,但这已经是一个问题了,是否有任何在线文档可供您参考?
最佳答案
首先,假设您正在使用Nuget的最新SDK DLL:Microsoft.CrmSdk.XrmTooling.CoreAssembly 8.2.0.5。
我从未将连接包装在using
语句中,而且我认为我从未见过完成此操作的示例。在拥有工具库之前,有一些“过去”的示例,其中创建OrganizationServiceProxy
的调用被包装在using
语句中,这导致许多没有经验的开发人员发布具有连接性能问题的代码。
幸运的是,大多数问题已通过Xrm.Tooling库为我们修复。
使用CrmServiceClient
创建连接对象:CrmServiceClient crmSvc = new CrmServiceClient(@"...connection string goes here...");
现在,如果我创建一个OrganizationServiceContext
(或早期绑定的等效对象)对象,则会将其包装在using
中,以便在完成我的工作单元时可以确定地将其丢弃。
using (var ctx = new OrganizationServiceContext(crmSvc))
{
var accounts = from a in ctx.CreateQuery("account")
select a["name"];
Console.WriteLine(accounts.ToList().Count());
}
Xrm.Tooling库可以为您处理连接通道和身份验证方面的所有其他事务。除非您每次指定创建一个新通道(通过在连接字符串上添加'RequireNewInstance = true'或在调用
useUniqueInstance
时将true
设置为new CrmServiceClient
),否则库将重用现有的已认证通道。我使用以下代码进行了快速验证测试:
void Main()
{
var sw = new Stopwatch();
sw.Start();
var crmSvc = GetCrmClient();
Console.WriteLine($"Time to get Client # 1: {sw.ElapsedMilliseconds}");
crmSvc.Execute(new WhoAmIRequest());
Console.WriteLine($"Time to WhoAmI # 1: {sw.ElapsedMilliseconds}");
var crmSvc2 = GetCrmClient();
Console.WriteLine($"Time to get Client # 2: {sw.ElapsedMilliseconds}");
crmSvc2.Execute(new WhoAmIRequest());
Console.WriteLine($"Time to WhoAmI # 2: {sw.ElapsedMilliseconds}");
}
public CrmServiceClient GetCrmClient()
{
return new CrmServiceClient("...connection string goes here...");
}
当我用
RequireNewInstance=true
运行它时,我得到以下控制台输出:显然,创建每个连接花费的时间差不多。
现在,如果将其更改为
RequireNewInstance=false
(这是默认设置),则会得到以下信息:哇,那是一个很大的不同。到底是怎么回事?在第二个调用中,Xrm.Tooling库使用现有的服务通道和身份验证(它已缓存)。
您可以进一步执行此步骤,并将
new CrmServiceClient
调用包装在using
中,您将获得相同的行为,因为处理return实例不会破坏高速缓存。因此,这将返回与上述类似的时间:
using (var crmSvc = GetCrmClient())
{
Console.WriteLine($"Time to get Client # 1: {sw.ElapsedMilliseconds}");
crmSvc.Execute(new WhoAmIRequest());
Console.WriteLine($"Time to WhoAmI # 1: {sw.ElapsedMilliseconds}");
}
using (var crmSvc2 = GetCrmClient())
{
Console.WriteLine($"Time to get Client # 2: {sw.ElapsedMilliseconds}");
crmSvc2.Execute(new WhoAmIRequest());
Console.WriteLine($"Time to WhoAmI # 2: {sw.ElapsedMilliseconds}");
}
为了简化代码,我通常创建一个静态类(也可以使用一个单例,但通常会显得过大)以返回
CrmServiceClient
对象。这样,如果我想更改有关如何建立连接的任何内容,我的代码就不会被new CrmServiceClient
调用所困扰。要从根本上回答有关
using
的问题,我们不需要使用它,因为没有任何要发布的内容。您的所有方法调用都将执行完成或引发异常,因此即使GC花费了一段时间,那里也没有开放的连接会占用资源和/或阻止其他活动。关于asp.net-mvc-5 - 在Web应用程序中连接CRM的最佳实践,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46496210/