2012-07-06 44 views
9

Tôi muốn cung cấp chuỗi kết nối cho cơ sở dữ liệu của mình khi chạy. Tôi đang sử dụng khung Entity. Đây là những gì tôi có cho đến nayChuỗi kết nối thời gian chạy của khung thực thể

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

Để sử dụng mã ở trên, tôi đã cố gắng

//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()) 

Đoạn mã trên đã cho tôi một lỗi nói rằng "từ khóa Nhà cung cấp không được hỗ trợ". Để cố gỡ lỗi này, tôi đã thử như sau

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") 

Bây giờ, tôi gặp lỗi "từ khóa siêu dữ liệu không được hỗ trợ". Vì vậy, tôi đã thay đổi mã của mình thành

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

Bây giờ tôi gặp lỗi "từ khóa nhà cung cấp không được hỗ trợ". Vì vậy, tôi lại thay đổi mã của mình thành

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

và giờ nó hoạt động !. Câu hỏi của tôi là: làm cách nào để chỉ định nhà cung cấp và siêu dữ liệu trong thời gian chạy? Có vẻ như chỉ chuỗi kết nối đang được chấp nhận. Tôi đang sử dụng thực thể 4.3.1 từ Nuget.

Cảm ơn

Trả lời

10

edmx dựa EF yêu cầu "Nhà cung cấp" và "Metadata" nội dung. EF dựa trên mã đầu tiên không yêu cầu điều này, chỉ yêu cầu chuỗi kết nối thông thường. Bạn có thể sử dụng một số SqlConnectionBuilder (thay vì EntityConnectionStringBuilder) để tạo chuỗi kết nối bình thường này nếu bạn muốn. Nhưng như bạn đã thấy, bạn chỉ cần chỉ định chi tiết kết nối thực tế. Nhà cung cấp và Siêu dữ liệu không cần thiết trong mô hình đầu tiên của Mã DbContext của EF 4.3.1.

+1

Vì vậy, tôi sẽ làm gì nếu tôi cần kết nối với Oracle hoặc MySQL bằng mã đầu tiên? –

+3

Chuỗi kết nối EF có 'Nhà cung cấp =" System.Data.Entity "' và 'ConnectionString =" res: //big.csdl | res: //ball.ssdl | res: //mud.msl; nhà cung cấp kết nối chuỗi = " ... "'. Các chuỗi kết nối thông thường có các chi tiết 'Provider =" System.Data.Client "' (hoặc Oracle hoặc MySql) và 'ConnectionString =" để kết nối với nó "'. Hai tham số này thường có trong app.config hoặc web.config, nhưng bạn đang chọn tạo chúng theo cách động. Trong EF Code Đầu tiên, bạn lấy con đường thứ hai. Trong vùng đất EDMX, bạn phải nhúng chi tiết của đường dẫn thứ hai vào "Chuỗi kết nối nhà cung cấp" của đường dẫn đầu tiên. Nó xấu. – robrich

7

Lớp EntityConnectionStringBuilder có thể được sử dụng để xác định nhà cung cấp và siêu dữ liệu trong thời gian chạy

ví dụ

thực thể varConnectionStringBuilder = new EntityConnectionStringBuilder(); entityConnectionStringBuilder.Provider = "System.Data.SqlClient"; entityConnectionStringBuilder.Metadata = "res: // /Example.csdl|res:// /Example.ssdl|res://*/Example.msl";

Hãy xem để biết thêm về CSDL, SSDL & MSDL trong Metadata tập tin

+0

vâng , đó là những gì tôi đã thử và nó không hoạt động. Mã cho tôi lỗi "từ khóa nhà cung cấp không được hỗ trợ hoặc siêu dữ liệu không được hỗ trợ". Vui lòng xem bài viết gốc để biết chi tiết –

+0

Nhà cung cấp = "System.Data.SqlClient" không nên là Nhà cung cấp = "System.Data.EntityClient" – HatSoft

+0

Điều đó có thể đúng nhưng thay đổi nhà cung cấp không trợ giúp ngay bây giờ vì tôi nhận được như vậy lỗi nói rằng từ khóa "nhà cung cấp" không được hỗ trợ. –

4

Tôi đi theo này link

và cũng này một

Làm thế nào để sử dụng EF Code-First mà không có một tập tin app.conf?

Về cơ bản những gì tôi làm gần giống như bạn, tạo một hàm tạo với một chuỗi và gọi cơ sở.

Nhưng tôi cũng đặt nhà cung cấp trong công cụ xây dựng này.

đây là một ví dụ

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

Bằng cách đó bạn có thể chỉ định các nhà cung cấp. Và bạn sẽ không gặp lỗi từ khóa của nhà cung cấp vì bạn không cần phải chỉ định trong chuỗi kết nối

Đây là cách tôi gọi nó.

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

Hy vọng rằng sẽ giúp đưa tôi thời gian dài để tìm thấy nó

7

xây dựng trên 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 - điều này có hiệu quả với npgsql không? – BKSpurgeon

+0

@BKSpurgeon Tôi đã không phải sử dụng DB đó, hãy cho chúng tôi biết những gì bạn tìm hiểu :-) –

+0

có một lớp người xây dựng chuỗi - nhưng tôi thấy nó hơi lỗi và một chút ác mộng cho noob - tôi chạy với mysql cuối cùng. – BKSpurgeon

2

Đó là câu hỏi cũ nhưng có lẽ nó sẽ hữu ích cho một ai đó

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

Cảm ơn bạn đã trả lời câu trả lời này! Vấn đề tôi phải đối mặt là tôi không sử dụng CSDL, SSDL hoặc MSDL trong mã của mình, vì vậy tôi không có gì để đặt thuộc tính Siêu dữ liệu thành (cũng không thể đặt trong "res: // *"). Bằng cách làm theo đề nghị của bạn, tôi đã có thể vượt qua giới hạn này. Nhiều đánh giá cao! –

Các vấn đề liên quan