对 master 数据库的查询在数据库优先中引发无意代码第一异常



在为SQL服务器主数据库创建模型时遇到巨大问题。我首先选择了数据库,没有包含任何对象,所以我有一个空模型:

主型号.cs:

*//------------------------------------------------------------------------------
// <auto-generated>
//     This code was generated from a template.
//
//     Manual changes to this file may cause unexpected behavior in your application.
//     Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------*

masterEntities.cs:

  public partial class masterEntities
  {
    static masterEntities()
    {
      // don't let EF modify the database schema...
      Database.SetInitializer<masterEntities>(null);
    }
    public masterEntities(string connectionString)
        : base(connectionString)
    {
    }
}

目标是对 master 数据库触发查询,以确定当前用户是否具有 serveradmin 权限(稍后创建新数据库):

   public bool UserHasAdminPrivilegesAtDatabaseServer(DatabaseServer databaseServer)
    {
      var sqlBuilder = new SqlConnectionStringBuilder
      {
        DataSource = databaseServer.Server,
        InitialCatalog = "master",
        PersistSecurityInfo = true,
        IntegratedSecurity = true,
        MultipleActiveResultSets = false,

      };
      //assumes a connectionString name in .config of MyDbEntities
      var entityConnectionStringBuilder = new EntityConnectionStringBuilder
      {
        Provider = "System.Data.SqlClient",
        ProviderConnectionString = sqlBuilder.ConnectionString,
        Metadata = "res://*/masterModel.csdl|res://*/masterModel.ssdl|res://*/masterModel.msl",
      };
      var connstring = entityConnectionStringBuilder.ProviderConnectionString;
      using (var context = new masterEntities(connstring))
      {
        const string sql = "SELECT IS_SRVROLEMEMBER('sysadmin')";//"SELECT IS_SRVROLEMEMBER('sysadmin')";
        var a = context.Database.SqlQuery<int>(sql).FirstOrDefault();
        return a == 1;
      }
    }

现在的问题是,EF 触发了事件 OnModelCreateating,该事件在 DatabaseFirst 模式下按如下方式实现:

    using System;
    using System.Data.Entity;
    using System.Data.Entity.Infrastructure;
    public partial class masterEntities : DbContext
    {
        public masterEntities()
            : base("name=masterEntities")
        {
        }
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            throw new UnintentionalCodeFirstException();
        }
    }

我们在这里:抛出新的无意代码第一异常();不知何故,EF 想在主数据库中创建一些东西;即使我们设置了全局静态属性,它也不应该,模型本身为空:Database.SetInitializer<masterEntities>(null) ;

在这里找到了答案:https://stackoverflow.com/a/26120762/5172266

元数据必须正确填写:

    private static string GetConnectionString(string model, string providerConnectionString)
{
  var efConnection = new EntityConnectionStringBuilder();
  // or the config file based connection without provider connection string
  // var efConnection = new EntityConnectionStringBuilder(@"metadata=res://*/model1.csdl|res://*/model1.ssdl|res://*/model1.msl;provider=System.Data.SqlClient;");
  efConnection.Provider = "System.Data.SqlClient";
  efConnection.ProviderConnectionString = providerConnectionString;
  // based on whether you choose to supply the app.config connection string to the constructor
  efConnection.Metadata = string.Format("res://*/correctModel.{0}.csdl|res://*/correctModel.{0}.ssdl|res://*/correctModel.{0}.msl", model);
  // Make sure the "res://*/..." matches what's already in your config file.
  return efConnection.ToString();
}

解释(功劳归于鲁莽)

您得到的异常是因为当您传递纯 SQL 连接字符串时,它假定您首先使用代码,因此它会调用 OnModelCreation 事件。如上所示包含"元数据"部分时,这会告知 EF 这是一个完整的 EF 连接字符串。

最新更新