2012-07-06 11 views
9

Chciałbym podać ciąg połączenia dla mojej bazy danych w czasie wykonywania. Korzystam z Entity Framework. To, co mam tak dalekoŁańcuch połączenia jednostki wykonawczej Entity Framework

class MyClassDBContext:DbContext 
{ 
    public MyClassDBContext(string str) : base(str) 
    { 
    this.Database.Connection.ConnectionString = str; 
    } 
} 

Aby użyć powyższy kod, próbowałem

//create connection string 
EntityConnectionStringBuilder myConn = new EntityConnectionStringBuilder(); 
myConn.Provider = "System.Data.SqlClient"; 
myConn.ProviderConnectionString = "user id=xxxx;password=xxxx;server=localhost;database=xxxx;connection timeout=30"; 

//inject the connection string at runtime 
MyClassDBContext a = new MyClassDBContext(myConn.ToString()) 

Powyższy kod dał mi błąd mówiąc „Hasło Provider not supported”. Aby próbować debugować ten błąd, próbowałem następujące

MyClassDBContext a = new MyClassDBContext("metadata=res://*/Model.csdl|res://*/Model.ssdl|res://*/Model.msl;provider=System.Data.SqlClient;provider connection string=user id=xxxx;password=xxxx;server=localhost;database=xxxx;connection timeout=30") 

Teraz mam błąd mówiąc „słowo kluczowe metadanych nie jest obsługiwany”. Więc zmieniłem kod na

MyClassDBContext a = new MyClassDBContext("provider=System.Data.SqlClient;provider connection string=user id=xxxx;password=xxxx;server=localhost;database=xxxx;connection timeout=30") 

Teraz otrzymałem komunikat o błędzie "słowo kluczowe dostawcy nie jest obsługiwane". Więc ponownie zmieniłem kod na

MyClassDBContext a = new MyClassDBContext("user id=xxxx;password=xxxx;server=localhost;database=xxxx;connection timeout=30") 

, a teraz działa!. Moje pytanie brzmi: jak określić dostawcę i metadane w czasie wykonywania? Wygląda na to, że akceptowany jest tylko ciąg połączenia. Używam Entity 4.3.1 od Nuget.

Dzięki

Odpowiedz

10

edmx wymagają „dostawca” i „metadane” treści. Oparty na kodzie EF EF nie wymaga tego, wymagając jedynie zwykłego ciągu połączenia. Możesz użyć SqlConnectionBuilder (zamiast EntityConnectionStringBuilder), aby zbudować ten normalny ciąg połączenia, jeśli chcesz. Ale jak widzisz, musisz tylko określić rzeczywiste szczegóły połączenia. Dostawca i metadane nie są potrzebne w paradygmacie DbContext Code EF 4.3.1.

+1

Co powinienem zrobić, gdybym najpierw musiał połączyć się z Oracle lub MySQL za pomocą kodu? –

+3

Łańcuch połączenia EF ma wartość 'Provider =" System.Data.Entity "' i 'ConnectionString =" res: //big.csdl | res: //ball.ssdl | res: //mud.msl; provider connection string = " ... "'. Regularne ciągi połączeń zawierają szczegóły 'Provider =" System.Data.Client "' (lub Oracle lub MySql) i 'ConnectionString =", aby się z nim połączyć ". Te dwa parametry są zwykle w pliku app.config lub web.config, ale wybierasz je dynamicznie. W kodzie EF Najpierw wybierasz drugą ścieżkę. W EDMX land, musisz osadzić szczegóły drugiej ścieżki w "Ścieżce połączenia dostawcy" pierwszej ścieżki. To jest brzydkie. – robrich

7

Klasa EntityConnectionStringBuilder mogą być używane do określenie usługodawcy i metadanych w czasie wykonywania

np

var entityConnectionStringBuilder = nowy EntityConnectionStringBuilder(); entityConnectionStringBuilder.Provider = "System.Data.SqlClient"; entityConnectionStringBuilder.Metadata = "res: // /Example.csdl|res:// /Example.ssdl|res://*/Example.msl";

Proszę zobaczyć więcej na CSDL, SSDL & MSDL w metadanych pliku EF oparty

+0

tak , właśnie tego próbowałem i to nie działało. Kod daje mi błąd "dostawca słowa kluczowego nie jest obsługiwany lub słowo kluczowe nie jest obsługiwane". Proszę zobaczyć oryginalny post po szczegóły –

+0

Dostawca = "System.Data.SqlClient" nie powinien to być Provider = "System.Data.EntityClient" – HatSoft

+0

To może być prawda, ale zmiana dostawcy nie pomaga w tej chwili, ponieważ otrzymuję to samo błąd informujący, że słowo kluczowe "provider" nie jest obsługiwane. –

4

Śledziłem tę link

i również ten

Jak używać EF kodu najpierw bez pliku app.conf?

Zasadniczo to, co robię, jest prawie takie jak Ty, utwórz konstruktora z ciągiem i wywołaj bazę.

Ale ustawiłem również dostawcę w tym konstruktorze.

oto przykład

public Context(string ConnectionString) : base(ConnectionString) { 
    Database.DefaultConnectionFactory = new SqlCeConnectionFactory("Oracle.DataAccess.Client"); 
} 

W ten sposób można określić dostawcę. I nie otrzymasz błędu słowa kluczowego dostawcy, ponieważ nie musisz podawać w łańcuchu połączenia

Oto jak to nazywam.

var dbCont = new ClassLibrary1.Models.Context("DATA SOURCE=xxx;PASSWORD=xxx;USER ID=xxx"); 

nadzieję, że pomoże zajęło mi dużo czasu, aby znaleźć to

7

budynek na HatSoft's answer:

var entityConnectionStringBuilder= new EntityConnectionStringBuilder(); 
entityConnectionStringBuilder.Provider = "System.Data.SqlClient"; 
entityConnectionStringBuilder.ProviderConnectionString = <your SQL Server connection string>; 
entityConnectionStringBuilder.Metadata = "res://*"; 

MyClassDBContext a = new MyClassDBContext(entityConnectionStringBuilder.ToString()); 
+0

hi thx @DavidMcClelland - czy to zadziała na npgsql? – BKSpurgeon

+0

@BKSpurgeon Nie musiałem jeszcze używać tego DB, daj nam znać, co się dowiesz :-) –

+0

Tak, istnieje klasa konstruktora sznurków - ale znalazłem ją trochę powikłaną i trochę koszmaru dla nooba - w końcu uruchomiłem mysql. – BKSpurgeon

2

To stare pytanie, ale może to być przydatne dla kogoś

var provider = (DbProviderFactory)System.Data.Entity.DbConfiguration 
      .DependencyResolver 
      .GetService(typeof(DbProviderFactory), "invariant provider name"); 

     var conn = provider.CreateConnection(); 
     //conn.ConnectionString = "sample connection string"; 

     DbInterception.Dispatch.Connection.SetConnectionString(conn, new DbConnectionPropertyInterceptionContext<string>() 
      .WithValue("sample connection string")); 

return new SampleDbContext(conn,true); 
+0

Dziękuję za tę odpowiedź! Problem, z jakim miałem do czynienia, polegał na tym, że nie używam kodu CSDL, SSDL lub MSDL w moim kodzie, więc nie miałem nic do ustawienia właściwości metadanych (nie mogłem wstawić "res: // *"). Postępując zgodnie z Twoją sugestią, udało mi się przezwyciężyć to ograniczenie. Bardzo doceniane! –

Powiązane problemy