2013-06-03 13 views
16

Ho un metodo di estensione su DbContext dove voglio fare un SqlBulkCopy. Quindi ho bisogno di un SqlConnection. La connessione da DbContext proviene tuttavia dal tipo DbConnection. Tra un paio di altre cose che ho provato questo:Ottenere SqlConnection da DbConnection

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

problema è che la password non è presente (probabilmente per motivi di sicurezza).

Un'altra cosa che ho provato è upcasting:

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

Che in realtà presuppone l'DbConnection è uno SqlConnection. In questo caso molto specifico, è già sbagliato. Sto usando MVC MiniProfiler che avvolge la connessione in un EFProfiledDbConnection. EFProfiledDbConnection non eredita da SqlConnection.

Altre idee? Grazie in anticipo!

+0

No, né SqlConnection nè SqlBulkCopy fare accettare un DbConnection come argomento del costruttore. –

+1

prova a trasmettere il 'DbConnection' a' SqlConnection' –

+0

Scusa, l'ho già provato ma ho dimenticato di aggiungerlo alla domanda. Ho aggiornato la mia domanda. –

risposta

7

Uno dei possibili modi per risolvere questo problema è aggiungere Persist Security Info=true alla stringa di connessione.

+0

Non ho molta familiarità con Persist Security Info. Sembra un po 'drastico per qualcosa che si spera possa essere risolto un po' più elegante. Quali sono gli svantaggi? –

+1

Persist Security Info mantiene la password in memoria, altrimenti viene cancellata rendendo inutilizzabile la stringa di connessione quando si tenta di riutilizzarla. Non penso ci siano degli svantaggi che dovresti preoccuparti, assumendo che la stringa di connessione sia fornita nel file di configurazione. –

+1

L'approccio più elegante sarebbe passare alla sicurezza integrata in modo che non ci sia username/password nella stringa di connessione, ma piuttosto - 'Integrated security = true'. –

11

Bene, se entrambi possono condividere lo stesso Connection String allora immagino che siano entrambi SqlConnection.

Prova a modificare:

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

Scusa, l'ho già provato ma ho dimenticato di aggiungerlo alla domanda. Ho aggiornato la mia domanda. –

+8

Per i futuri browser che guardano questa domanda. Sebbene questa risposta non funzioni per l'OP, in generale DbConnection è spesso un'istanza di SqlConnection. Quindi, dovresti controllare e vedere se questo funzionerà per la tua istanza specifica. –

1

È possibile controllare il tipo di dbContext.Database.Connection. Se è un EFProfiledDbConnection è possibile ottenere la proprietà WrappedConnection, che restituisce un valore DbConnection. Questo è un SqlConnection se si utilizza SQL Server.

+0

Potrei farlo se non c'è davvero altra soluzione. Ma penso che sia abbastanza brutto. Il controllo dei tipi puzza di codice errato ed è qualcosa che piuttosto prevengo. Ciò significa anche aggiungere un riferimento a MiniProfiler in questo assembly (MiniProfiler è ora referenziato solo nel mio assieme Web). Un altro svantaggio è che in futuro potrebbe non esserci un altro tipo di DbConnection che non ho preso in considerazione e il codice si interrompe nuovamente. –

+0

Puoi racchiuderlo nel contesto stesso, ad es. in un metodo 'GetConnection()'. Altri assemblaggi non avrebbero bisogno di un riferimento a MiniProfiler. –

2

unico modo che ho trovato finora è quello di utilizzare System.Configuration libreria:

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

a volte si desidera utilizzare una connessione esistente a causa di transazioni rasons. – gsharp

2

Ho avuto un problema simile con ProfiledConnection (HibernatingRhinos.Profiler.Appender.ProfiledDataAccess.ProfiledConnection)

e cosa avevo bisogno era SqlConnection, questo ha fatto il trucco:

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