запрос к главной базе данных создает UnintentionalCodeFirstException в DatabaseFirst

Возникли огромные проблемы с созданием модели для SQL Server master db.
Сначала я выбрал базу данных, не включил никаких объектов, поэтому у меня есть пустая модель:

masterModel.цезий:

*//------------------------------------------------------------------------------
// <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.цезий:

  public partial class masterEntities
  {

    static masterEntities()
    {
      // don't let EF modify the database schema...
      Database.SetInitializer<masterEntities>(null);
    }

    public masterEntities(string connectionString)
        : base(connectionString)
    {

    }
}

Цель состоит в том, чтобы запустить запрос к главной базе данных, чтобы узнать, если текущий пользователь имеет права 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 запускает событие OnModelCreating, которое реализуется следующим образом в режиме 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();
        }

    }

и вот мы здесь: throw new UnintentionalCodeFirstException();
Каким-то образом EF хочет создать некоторые вещи в master-db; даже когда мы задаем глобальное статическое свойство, это не должно, и сама модель пуста: Database.SetInitializer<masterEntities>(null);

1 ответ

  1. нашел ответ здесь: 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();
    }
    

    Объяснение (кредит идет reckface)

    Исключение, которое вы получаете, состоит в том, что когда вы передаете чистую строку подключения SQL, она предполагает, что вы работаете с кодом сначала, поэтому она вызывает событие OnModelCreation. Когда вы включаете раздел метаданных, как показано выше, это говорит EF, что это полная строка соединения EF.