首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >创建程序集失败,因为方法是不可见的,但是所有东西都是公共的。

创建程序集失败,因为方法是不可见的,但是所有东西都是公共的。
EN

Stack Overflow用户
提问于 2015-12-09 17:12:36
回答 1查看 453关注 0票数 1

我正在尝试将以前是一个大型数据库项目的CLR存储过程重新配置为一个核心逻辑项目和一个数据库项目,以分离我的关注点。因此,这些项目的架构如下:

代码语言:javascript
复制
  \src
     \Company.Core
         \CoreCode.cs
         \CoreCode2.cs
     \Company.Database
         \Programmability\Stored Procedures
             CmsSelectQueryStoredProcedure.cs
             ClrStoredProcedure2.cs

当我试图部署该项目时,会收到一系列错误消息:

代码语言:javascript
复制
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)

ClrStoredProcdure1.cs包含以下代码:

代码语言:javascript
复制
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*/}
    }
}

这些方法是公共的,我使用程序集属性使它们更加可见。我遗漏了什么吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-12-09 17:39:45

一个明确的问题是构造函数方法-- CmsSelectQueryStoredProcedure() --不能/永远不会被调用,因为它是一个实例方法,而且这些类从未被实例化。您需要以以下形式使用静态构造函数:

代码语言:javascript
复制
    static CmsSelectQueryStoredProcedure()
    {
        _cmsDataService = new CmsDataService();
    }

另一个可能是SqlProcedure的方法属性可能需要包含括号。意思是,使用这个:

代码语言:javascript
复制
[SqlProcedure()]

而不是这样:

代码语言:javascript
复制
[SqlProcedure]

另外,最好将Sql*类型用于SQLCLR方法的输入参数/输出参数/返回类型。也就是说,使用SqlString而不是常规的C# string

代码语言:javascript
复制
public static void ExecuteCmsSelectQuery(SqlString targetGroup, SqlString query, SqlString targetGroupUserName, SqlString targetGroupPassword)

然后通过它们都具有的.NET属性访问该参数的.Value类型:

代码语言:javascript
复制
targetGroup.Value

另外,你真的需要一个静态变量吗?这将要求大会被标记为UNSAFE,除非它也被声明为readonly

这一限制有很好的理由:每个程序集所有者每个数据库有一个AppDomain。也就是说,所有并发调用此代码的会话都将访问该(或任何)静态变量的完全相同的引用。执行上下文不是每个会话,而是同时在所有会话之间共享。

此外,名称空间名称本身也可能是一个问题。我通常从不为SQLCLR代码使用名称空间,因为它们需要嵌入到CREATE语句的AS EXTERNAL NAME子句的类名部分中。例如,我猜想您存储的proc最终会是:

代码语言:javascript
复制
[MyAssembly].[KK.Corporate.ServerGroupQuery.Database.Programmability.Stored_Procedures.CmsSelectQueryStoredProcedure].[ExecuteCmsSelectQuery]

我还没有尝试过这样的长度,也没有使用多个句点和下划线,所以可能会很好。

有关使用SQLCLR的更多信息,请参见我就此主题编写的关于Server的系列文章(需要免费注册才能阅读该站点上的文章;我无法控制该策略):

通往SQLCLR的楼梯

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34184880

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档