从DLL本身获取SQL Server CLR“创建程序集”位置

时间:2017-02-05 21:30:43

标签: .net sql-server sqlclr

程序集存储在数据库中,您可以像这样获取注册位置:

SELECT af.name FROM sys.assemblies a
INNER JOIN sys.assembly_files af
        ON a.assembly_id = af.assembly_id
WHERE a.name = 'MyAssemblyName'

但是,我想在不问SQL Server的情况下得到它,我想从正在运行的程序集中获取它。 Assembly.GetExecutingAssembly().Location返回空白。 AppDomain.Current.BaseDirectory返回SQL Server的binn路径。

当我使用CREATE ASSEMBLY注册程序集时,我给了它一条路径。我想走那条路。

编辑(解决方案)

毕竟我不得不咨询数据库服务器。但它并没有那么糟糕,因为至少连接字符串不是硬编码的。

[SqlFunction(DataAccess = DataAccessKind.Read, SystemDataAccess = SystemDataAccessKind.Read)]
public static SqlString AssemblyLocation()
{
  using (var connection = new SqlConnection("context connection=true"))
  {
    var cmd = new SqlCommand($"SELECT af.name FROM sys.assemblies a INNER JOIN sys.assembly_files af ON a.assembly_id = af.assembly_id WHERE a.name = '{AssemblyName().Value}'", connection);
    connection.Open();
    return cmd.ExecuteScalar().ToString();
  }
}

[SqlFunction(DataAccess = DataAccessKind.Read, SystemDataAccess = SystemDataAccessKind.Read)]
public static SqlString AssemblyName()
{
  return typeof(StoredProcedures).Assembly.GetName().Name;
}

[SqlFunction(DataAccess = DataAccessKind.Read, SystemDataAccess = SystemDataAccessKind.Read)]
public static SqlString WebApiRoot()
{
  var config = ConfigurationManager.OpenExeConfiguration(AssemblyLocation().Value);
  return config.AppSettings.Settings["WebApiRoot"].Value;
}

2 个答案:

答案 0 :(得分:0)

  

当我使用CREATE ASSEMBLY注册程序集时,我给了它一条路径。我想走那条路。

这是不可能的,因为该路径仅用于将程序集读入数据库。您在content 中看到的sys.assembly_files列是程序集/ DLL。它现在存在于数据库中。这就是CREATE ASSEMBLY的作用。这比旧的扩展存储过程(XPs)框架更有优势,因为没有外部依赖性;备份数据库时,程序集将备份它,因为数据驻留在数据库中,而不是文件系统中。

答案 1 :(得分:0)

从其他答案的评论中,听起来你想要一个上下文连接。从文档中的示例:

SqlConnection connection = new SqlConnection("context connection=true")