从Dynamics CRM SDK获取数据库连接字符串

问题描述:

以找到所有拥有多个开放式电话呼叫的客户为例。在SQL中,一个HAVING子句可以让你获得大部分的方式。在CRM SDK中,这会变得更加困难,我敢打赌,只有CRM服务器才能处理通过网络发送的更多数据。从Dynamics CRM SDK获取数据库连接字符串

因此,我希望我的插件,应用程序,自定义工作流通过过滤视图读取数据库,然后通过Web服务更改需要的内容。

问题:如何从SDK中获取组织背后数据库的数据库连接字符串?

当然,我知道它现在是什么,可以硬编码或配置它。但我希望用户使用发现服务和应用程序找到他们的CRM实例来处理其余的事情。

刚刚从一个快速测试,简单的SQL

SELECT subject, phonenumber, createdon FROM FilteredPhoneCall WHERE activityid = @phoneCallID 

比SDK的检索方法快4倍左右。

我不知道从SDK/WebServices访问该信息的任何方式,我通常将连接字符串保存在配置文件或项目设置中。

有很多,可以根据安装设置改变的因素:

  • DB服务器名称
  • 安装型(内部部署,IFD等)
  • DB身份验证(集成,密码等)

但是,如果您在本地部署中使用集成安全性,您可能会随时随地创建连接字符串...

string dbServerName = "SERVERNAME"; 
string orgName = getOrgNameFromDiscoveryService(); 

string connectionString = String.Format("Data Source={0};Initial Catalog={1}__MSCRM;Integrated Security=True", dbServerName, orgName); 

//create sql connection 
+0

服务器名称是症结所在。我处理场所安装,并使用集成身份验证,因此这些都不是(至少对我而言)。 – 2011-06-17 13:09:01

据我所知,没有办法从组织服务获取数据库服务器名称。您可以使用部署服务(请参阅http://worldofdynamics.blogspot.com/2011/12/dynamics-crm-2011-c-code-for-retrieving.html)检索它,但除非您是部署管理员 - 即使是检索,该服务也没有用处。

我知道,查看数据库信息的唯一方法是将视图/高级查找导出到动态电子表格 - 连接信息嵌入在Excel XML中。

我开发了一个静态方法,给定Org Url,将下载一个动态电子表格并解析出连接字符串。

/// <summary> 
    /// Given a Dynamics CRM Org URL, retrieve the Database Connection string 
    /// </summary> 
    /// <param name="crmOrgUrlBase"></param> 
    /// <returns></returns> 
    private static string GetCrmDatabaseConnectionString(string crmOrgUrlBase) 
    { 
     string cleanurl = crmOrgUrlBase.ToLowerInvariant().Trim().Replace("/xrmservices/2011/organization.svc", ""); 
     { 
      int mainPos = cleanurl.IndexOf("/main.aspx"); 
      if (mainPos > 0) 
      { 
       cleanurl = cleanurl.Substring(0, mainPos); 
      } 
     } 

     string requestPayload = @"xdpi=96&exportType=list&useSqlQuery=1&fetchXml=%3Cfetch+distinct%3D%22false%22+no-lock%3D%22false%22+mapping%3D%22logical%22+page%3D%221%22+count%3D%2250%22+returntotalrecordcount%3D%22true%22%3E%3Centity+name%3D%22systemuser%22%3E%3Cattribute+name%3D%22systemuserid%22%2F%3E%3Cattribute+name%3D%22fullname%22%2F%3E%3Cattribute+name%3D%22fullname%22%2F%3E%3Corder+attribute%3D%22fullname%22+descending%3D%22false%22%2F%3E%3C%2Fentity%3E%3C%2Ffetch%3E%0D%0A&layoutXml=%3Cgrid+name%3D%22excelGrid%22+select%3D%220%22+icon%3D%220%22+preview%3D%220%22%3E%3Crow+name%3D%22result%22+id%3D%22systemuserid%22%3E%3Ccell+name%3D%22fullname%22+width%3D%22100%22%2F%3E%3C%2Frow%3E%3C%2Fgrid%3E%0D%0A"; 
     string url = cleanurl + "/_grid/print/export_live.aspx"; 

     string response = null; 


     using (var wc = new System.Net.WebClient()) 
     { 
      wc.UseDefaultCredentials = true; 
      wc.Headers.Add("Accept-Encoding", "gzip, deflate"); 
      wc.Headers.Add("Content-Type", "application/x-www-form-urlencoded"); 
      wc.Headers.Add("DNT", "1"); 
      response = wc.UploadString(url, requestPayload); 
     } 


     var xe = System.Xml.Linq.XElement.Parse(response); 


     System.Xml.Linq.XNamespace nn = "urn:schemas-microsoft-com:office:spreadsheet"; 
     System.Xml.Linq.XNamespace nn2 = "urn:schemas-microsoft-com:office:excel"; 


     var connectionEl = xe.Element(nn + "Worksheet").Element(nn2 + "QueryTable").Element(nn2 + "QuerySource").Element(nn2 + "Connection"); 

     string rawString = connectionEl.Value; 

     Regex rex = new Regex("SERVER=([^;]+);DATABASE=([^;]+)", RegexOptions.Compiled); 

     var m = rex.Match(rawString); 

     string server = m.Groups[1].Value; 
     string database = m.Groups[2].Value; 

     return "DATA SOURCE=" + server +";INITIAL CATALOG=" + database + ";Integrated Security=SSPI"; 
    } 

它使用针对用户一个简单的查询 - 查询其实并不重要,因为我们需要的是数据库连接字符串。

我原来的博客文章是在这里: http://www.shulerent.com/2015/01/19/get-the-sql-server-and-database-name-from-dynamics-crm/

+0

感谢您分享此代码段。它为我工作。最初,我遇到了(401)未经授权的错误。然后,我在WebClient上添加了凭证,并且完美运行。再次感谢。 – 2017-01-30 23:47:50