2015-12-09 16 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

我会先解决构造函数问题并重新编译。如果您仍然遇到错误,也许尝试使用更简单的命名空间名称,或者根本没有? –

相关问题