为sql server master db创建模型存在巨大问题。 我首先选择了数据库,没有包含任何对象,所以我是一个空模型:
masterModel.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会触发事件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();
}
}
我们在这里:抛出新的UnintentionalCodeFirstException();
不知何故EF希望在master-db中创建一些东西;即使我们设置全局静态属性,它也不应该是模型本身为空:Database.SetInitializer<masterEntities>(null)
;
答案 0 :(得分:0)
在这里找到答案:https://stackoverflow.com/a/26120762/5172266
必须正确填充MetaData:
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连接字符串时,它假定您首先使用Code,因此它调用OnModelCreation事件。当您包含如上所示的MetaData部分时,它告诉EF它是一个完整的EF连接字符串。