2016-02-25 3 views
0

В настоящее время я настраиваю систему, в которой базовая защита на стороне сервера для подключения SQL-сервера к клиенту достигается с помощью представлений для каждого пользователя (аутентификация Windows).
Основная таблица Entries, что держит все данные получилиEntity Framework OnModelCreating - проверка отсутствующих DB-объектов

DENY SELECT, UPDATE, INSERT, DELETE ON [dbo].[Entries] FOR public 

, так что единственный способ получить доступ к данным для пользователей, чтобы использовать их соответствующий вид ENTRIES_USER («User» является заполнителем), который явно получает a

GRANT SELECT, INSERT, UPDATE, DELETE ON [dbo].[Entries_USER] TO [DOMAIN\user] 

. Кроме того, разрешения по умолчанию для public сокращены, поэтому никто не может читать из представления. Все работает до сих пор, и теперь идет классный материал.


Я подключения к этой БД с Entity Framework и «CodeFirst» (это на существующей БД, но отображение происходит во время выполнения), как это:

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 
    modelBuilder.Entity<Entry>().ToTable("Entries_" + Environment.UserName.ToUpper()); 
    modelBuilder.Entity<Project>().ToTable("Projects"); 
} 

Строка подключения позволяет ОС Windows Аутентификация, отображение объектов осуществляется с помощью аннотаций.
Что я не знаю, так это проверить, прежде чем пытаться выполнить Entity().ToTable(...), если эта таблица существует. Если это не так, я хочу сделать вызов хранимой процедуры, которая создаст новое представление для пользователя.
Я уже пытался поставить ToTable -Call внутри try-catch, но это не вызывает исключения, даже если он не может правильно подключиться.

Есть ли способ проверить заранее, без использования запрограммированных SQL-запросов, если таблица/представление, к которой я хочу привязать, уже существует? И если нет, могу ли я как-то отреагировать, когда EF-mapping не удалось, выполните какое-либо действие (вызов хранимой процедуры) и повторите попытку?

EDIT: Я решил, что проверка вручную с запросом должна быть в порядке, если нет «чистого» решения. Есть ли способ получить соединение с сервером в OnModelCreating, или мне нужно создать его самостоятельно?

ответ

0

Мне удалось получить эту работу, но только с собственным подключением. Я не могу использовать существующую, потому что DbContext не позволяет мне получить доступ к ней внутри OnModelCreating.

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 
    string viewname = "Entries_" + Environment.UserName.ToUpper(); 
    using (SqlConnection connection = new SqlConnection()) 
    using (SqlCommand initCmd = new SqlCommand("IF NOT EXISTS(select * FROM sys.views where name = @ViewName) exec dbo.spAddUser @User, @Domain", connection)) 
    { 
     // the connection string is the same one I use to create the DbContext 
     connection.ConnectionString = ConfigurationManager.ConnectionStrings["AppConnectionString"].ConnectionString; 
     initCmd.Parameters.AddWithValue("ViewName", viewname); 
     initCmd.Parameters.AddWithValue("User", Environment.UserName); 
     initCmd.Parameters.AddWithValue("Domain", GetDomain());    
     try 
     { 
      connection.Open(); 
      initCmd.ExecuteNonQuery(); 
     } 
     catch (SqlException e) 
     { 
      Debug.WriteLine(e.Message); 
      // TODO 
     } 
    } 
    modelBuilder.Entity<Entry>().ToTable(viewname); 
    modelBuilder.Entity<Project>().ToTable("Projects"); 
} 
Смежные вопросы