2013-06-03 21 views
16

Mam metodę przedłużenia na DbContext, gdzie chcę zrobić SqlBulkCopy. Dlatego potrzebuję SqlConnection. Połączenie z DbContext jest jednak typu DbConnection. Wśród kilku innych rzeczy, to próbowałem:Uzyskaj SqlConnection od DbConnection

var connection = new SqlConnection(dbContext.Database.Connection.ConnectionString); 

Problem jest, że hasło brakuje (prawdopodobnie ze względów bezpieczeństwa).

Inna sprawa, że ​​starałem się upcasting:

var bulk_copy = new SqlBulkCopy((SqlConnection)dbContext.Database.Connection); 

To rzeczywiście zakłada się DbConnection jest SqlConnection. W tym bardzo konkretnym przypadku już się nie udaje. Używam MVC MiniProfiler, który owija połączenie w EFProfiledDbConnection. Funkcja EFProfiledDbConnection nie dziedziczy po SqlConnection.

Jakieś inne pomysły? Z góry dziękuję!

+0

nie, ani SqlConnection ani SqlBulkCopy zrobić zaakceptować DbConnection jako argument konstruktora. –

+1

spróbuj upcasting 'DbConnection' na' SqlConnection' –

+0

Niestety, próbowałem już, ale zapomniałem dodać go do pytania. Zaktualizowałem moje pytanie. –

Odpowiedz

7

Jednym z możliwych sposobów obejścia tego problemu byłoby dodanie Persist Security Info=true do łańcucha połączenia.

+0

Nie jestem zaznajomiony z Persist Security Information. Brzmi trochę drastycznie, jeśli chodzi o coś, co z nadzieją można rozwiązać nieco bardziej elegancko. Jakie są wady? –

+1

Funkcja Persist Security Info zachowuje hasło w pamięci, w przeciwnym razie jest usuwana, przez co ciąg połączenia nie może być użyty podczas próby ponownego użycia. Nie sądzę, aby były jakieś wady, o które powinieneś się martwić, zakładając, że ciąg połączenia znajduje się w pliku konfiguracyjnym. –

+1

Najbardziej eleganckim podejściem byłoby przejście na zintegrowane zabezpieczenia, tak aby w łańcuchu połączenia nie było nazwy użytkownika/hasła, a raczej - "Zintegrowane bezpieczeństwo = true". –

11

Cóż, jeśli oba mogą mieć ten sam Connection String, to domyślam się, że oba są SqlConnection.

Spróbuj to zamiast:

var connection = rep.Database.Connection as SqlConnection; 
+0

Przepraszam, próbowałem już, ale zapomniałem dodać go do pytania. Zaktualizowałem moje pytanie. –

+8

Do każdej przyszłej przeglądarki, która przyjrzy się temu pytaniu. Chociaż ta odpowiedź nie działa dla PO, ogólnie DbConnection jest często instancją SqlConnection. Powinieneś więc sprawdzić i sprawdzić, czy to zadziała dla Twojej konkretnej instancji. –

1

Można sprawdzić typ dbContext.Database.Connection. Jeśli jest to EFProfiledDbConnection, możesz uzyskać jego właściwość WrappedConnection, która zwraca wartość DbConnection. To jest SqlConnection, jeśli używasz serwera Sql.

+0

Mogę to zrobić, jeśli tak naprawdę nie ma innego rozwiązania. Ale myślę, że to jest dość brzydkie. Sprawdzanie typów pachnie jak zły kod i jest to coś, co raczej zapobiegam. Oznacza to także dodanie odniesienia do MiniProfilera w tym zestawie (MiniProfiler jest teraz przywoływany tylko w moim zespole internetowym). Inną wadą jest to, że w przyszłości może istnieć inny typ DbConnection, którego nie uwzględniłem, a kod ponownie się zepsuje. –

+0

Możesz zawinąć go w samym kontekście, np. w metodzie 'GetConnection()'. Inne zespoły nie będą wymagać odniesienia do MiniProfilera. –

2

Jedynym sposobem znalazłem się tak daleko jest użycie System.Configuration Biblioteka:

var sqlConnString = ConfigurationManager.ConnectionStrings["your_conn_string_name"].ConnectionString; 
var bulkCopy = new SqlBulkCopy(sqlConnString); 
+0

Czasami chcesz użyć istniejącego połączenia ze względu na rany transakcji. – gsharp

2

miałem podobny problem z ProfiledConnection (HibernatingRhinos.Profiler.Appender.ProfiledDataAccess.ProfiledConnection)

i co Potrzebowałam SqlConnection, to wystarczyły:

ProfiledConnection profiledConnection = dbContext.Database.Connection as ProfiledConnection; 
SqlConnection sqlConnection = (SqlConnection)profiledConnection.Inner;