2015-12-09 32 views
1

我試圖重新配置一個CLR存儲過程,曾經是一個大型數據庫項目到一個核心邏輯項目和數據庫項目來分離我的顧慮。因此,項目的架構,像這樣:創建程序集失敗,因爲方法不可見 - 但一切都公開

\src 
    \Company.Core 
     \CoreCode.cs 
     \CoreCode2.cs 
    \Company.Database 
     \Programmability\Stored Procedures 
      CmsSelectQueryStoredProcedure.cs 
      ClrStoredProcedure2.cs 

當我嘗試部署項目,我收到了一系列錯誤消息:

CREATE ASSEMBLY for assembly 'MyAssembly' failed because assembly "MyAssembly" failed 
verification. Check it the referenced assemblies are up-to-date and trusted (for 
external_access or unsafe) to execute in the database. CLR verifier error messages if any 
will follow this message. 
MyAssembly.Programmability.Stored_Procedures.CmsSelectQueryStoredProcedure::.ctor Method is 
not visible. 
MyAssembly.Programmability.Stored_Procedures.CmsSelectQueryStoredProcedure:: 
.ExecuteCmsSelectQuery Method is not visible. 
(Many more of these) 

的ClrStoredProcedure1.cs包含此代碼:

using System; 
using System.Data.SqlClient; 
using System.Security; 
using Company.Core; 
using Microsoft.SqlServer.Server; 


[assembly: AllowPartiallyTrustedCallers(PartialTrustVisibilityLevel = PartialTrustVisibilityLevel.VisibleToAllHosts)] 


namespace KK.Corporate.ServerGroupQuery.Database.Programmability.Stored_Procedures 
{ 
    public class CmsSelectQueryStoredProcedure 
    { 
     public static CmsDataService _cmsDataService; 

     public CmsSelectQueryStoredProcedure() 
     { 
      _cmsDataService = new CmsDataService(); 
     } 

     const string InitialCatalog = "master"; 
     const int ConnectTimeout = 10; 

     [SqlProcedure] 
     public static void ExecuteCmsSelectQuery(string targetGroup, string query, string targetGroupUserName, string targetGroupPassword) 
     {/*etc*/} 
    } 
} 

這些方法是公開的,我使用一個程序集屬性使它們更加可見。有什麼我失蹤?

回答

2

一個明確的問題是,構造函數方法CmsSelectQueryStoredProcedure()不能永遠不會被調用,因爲它是一個實例方法,並且這些類永遠不會被實例化。您需要的形式爲使用靜態構造函數:

static CmsSelectQueryStoredProcedure() 
    { 
     _cmsDataService = new CmsDataService(); 
    } 

另一塊可能是對SqlProcedure方法屬性可能需要包括括號。這意味着,使用此:

[SqlProcedure()] 

,而不是這樣的:

[SqlProcedure] 

而且,最好是使用Sql*類型的輸入參數/輸出參數/返回類型SQLCLR方法。意思是用SqlString代替常規的C#string

targetGroup.Value 

另外,你真的需要一個靜態變量:

public static void ExecuteCmsSelectQuery(SqlString targetGroup, SqlString query, SqlString targetGroupUserName, SqlString targetGroupPassword) 

,然後通過.Value財產,他們都可以訪問該參數的.NET類型?這將要求大會被標記爲UNSAFE,除非它也被宣佈爲readonly

這個限制有很好的理由:每個裝配體擁有者每個數據庫有一個AppDomain。意思是,所有正在同時調用該代碼的會話將訪問該(或任何)靜態變量的完全相同的引用。執行上下文不是每個會話,而是在所有會話中同時共享。


此外,命名空間名稱本身可能是一個問題。我通常從不使用名稱空間來處理SQLCLR代碼,因爲它們需要嵌入到CREATE對象語句的AS EXTERNAL NAME子句的類名稱部分中。例如,我猜測你的存儲過程將結束是:

[MyAssembly].[KK.Corporate.ServerGroupQuery.Database.Programmability.Stored_Procedures.CmsSelectQueryStoredProcedure].[ExecuteCmsSelectQuery] 

我還沒有試過,長度或多個週期和下劃線,所以它可能只是罰款。


有關使用SQLCLR的詳細信息,請參閱該系列的,我對SQL Server的中央這個主題寫文章(免費註冊閱讀該網站上的文章必須的;我無法控制這種政策):

Stairway to SQLCLR

+0

啊構造函數 - 菜鳥錯誤!我仍然想知道爲什麼我會收到所有這些「方法不可見」消息。 –

+0

還不確定,因爲迄今爲止,一切都很順利。這就是爲什麼我提到命名空間,只是因爲沒有明顯的跳出來。 –

+0

我會先解決構造函數問題並重新編譯。如果您仍然遇到錯誤,也許嘗試使用更簡單的命名空間名稱,或者根本沒有? –

相關問題