2011-05-16 236 views
6

我試圖撥打這個電話在我的代碼:從實體框架連接字符串創建DataContext?

string conn = ConfigurationManager.ConnectionStrings["MyDBEntities"].ConnectionString; 
DataContext context = new DataContext(conn); 
Table<MyApp.Entities.Employee> myTable = context.GetTable<MyApp.Entities.Employee>(); 

這裏是我的連接字符串:

<connectionStrings> 
    <add name="MyDBEntities" connectionString="metadata=res://*/Entities.MyDB.csdl|res://*/Entities.MyDB.ssdl|res://*/Entities.MyDB.msl;provider=System.Data.SqlClient;provider connection string=&quot;Data Source=STEVEN-PC;Initial Catalog=MyDB;Integrated Security=True;MultipleActiveResultSets=True&quot;" providerName="System.Data.EntityClient" /> 
    <add name="MyDB" connectionString="Server=STEVEN-PC;Database=MyDB;Trusted_Connection=yes;" /> 
</connectionStrings> 

創建DataContext的,當我得到一個錯誤:不支持關鍵詞:「元數據」 。

如果我使用第二個連接字符串,當試圖獲取表時出現錯誤:'/'應用程序中的服務器錯誤。 類型「MyApp.Entities.Employee」未映射爲表。

我在這裏做錯了什麼?

回答

5

如果你想使用實體框架,你應該使用ObjectContext的,而不是DataContext的,因爲這是一個基礎來自Linq-To-Sql的類。

當您創建ADO.NET實體數據模型時,Visual Studio會生成(從數據庫嚮導完成生成模型或使用設計器之後),從ObjectContext派生的具有默認連接字符串的類(您選擇在嚮導)。 Here你可以從ADO.NET團隊中看到一個很好的教程如何開始使用EF。

你不應該直接使用ObjectContext,至少不是沒有手動創建元數據文件並在連接字符串中指向它們(從來沒有見過直接使用DataContext類,所以如果我錯了某人正確的我),因爲我上面提到的嚮導創建了各種映射數據 - 將SQL表/視圖/其他東西映射到實體類。

如果你想提供自己的連接到類,你可以用EntityConnectionStringBuilder以編程方式進行連接。

This是一個例子,如何使用它EntityConnectionStringBuilder從MSDN

編輯:我錯誤地寫了一篇關於DataContext的,如果它是EF基類設計器生成的代碼。它是casperOne爲Linq-To-Sql類聲明瞭一個基類。

改變了我的答案,以反映他的評論

+0

1)VS.NET不會生成派生自「DataContext」的類; 'DataContext'被LINQ-to-SQL使用,而不是LINQ-to-Entities。 VS.NET生成派生自「ObjectContext」的類。 2)沒有任何東西禁止直接使用ObjectContext。什麼VS.NET生成的是一個薄薄的一層,它有一些便利的方法;如果你願意,你可以很容易地自己調用這些方法,而且你根本不需要使用VS.NET生成的類,你只需要給它一個包含元數據信息的連接字符串(或者提供一個'MetadataWorkspace '分開)。 – casperOne 2011-05-16 05:04:34

+0

@casperOne 1)感謝您的澄清。這是我的代表。 (我很少看看由Linq-To-Sql和EF生成的類)2)我認爲雖然可以直接在EF中使用基類,但是我懷疑很多人會自己寫元數據文件。 – Michael 2011-05-16 06:41:25

1

ConnectionString中在EntityModel已經定義,所以你可以嘗試使用默認的連接如下:

using (context = new DataContext()) 
{ 
    var myTable = context.GetTable<MyApp.Entities.Employee>(); 
} 

您也可以嘗試以下方法:

MyApp.Entities.Employee myTable = context.GetTable<MyApp.Entities.Employee>(); 

編輯: GetTable < T>()將返回類型T,所以上面的語法將是正確的。

如果你想覆蓋連接字符串中,使用第二個連接字符串從你的web.config文件(MYDB)

+0

你有一個DataContext需要0個參數,但我沒有。你的DataContext在哪個命名空間中?我的是System.Data.Linq.DataContext。 – Steven 2011-05-16 03:11:58

+0

嗯..有趣。我創建ADO.NET實體數據模型時創建了我的DataContext。之後,我只需使用實體容器名稱的上下文。也許我的實施與你的實施不同,在這種情況下,我的答案對你沒有太大的幫助。 – Leons 2011-05-16 03:22:43

+0

你應該仍然可以使用你的dataContext和字符串MyDB.connectionconn = ConfigurationManager.ConnectionStrings [「MyDB」]。ConnectionString; DataContext context = new DataContext(conn);' – Leons 2011-05-16 03:24:05

9

你是混合和匹配LINQ-to-SQLLINQ-to-Entites;兩者不兼容。

當您使用LINQ-to-Entities創建實體模型時,它將創建一個從ObjectContext派生的對象,該對象將具有您將用於查詢基礎的IQueryable<T>實現。這ObjectContext也將有構造函數,採取適當的元數據映射實體模型到數據庫;這就是爲什麼實體框架連接字符串需要Metadata引用。

當您嘗試使用LINQ到SQL時,可以將它傳遞到DataContext類(或派生類)的常規數據庫連接。 DataContext以不同於實體框架的方式處理對象到數據庫的映射;它依靠模型上的屬性映射到表/列(分別使用TableAttributeColumnAttribute屬性)。使用實體框架創建實體時,這些屬性不存在。

注意:您可以使用LINQ-to-SQL的XML映射文件(與實體框架中使用的不同),但它不常用。

也就是說,最簡單的方法是選擇一個技術堆棧(LINQ到SQL或LINQ到實體)並堅持。

5

爲了以防萬一,這就是我所做的。我沒有Web.config中的連接,因爲我需要一個DropDownList來選擇連接。

string connDev = @"metadata=res://*/MyModel.csdl|res://*/MyModel.ssdl|res://*/MyModel.msl;provider=System.Data.SqlClient;provider connection string=""Server=MyDevServer;Database=MyDB;Integrated Security=True"""; 

EntityConnection ec = new EntityConnection(connDev); 

MyDBContext db = new MyDBContext(ec); 

var people = db.People.ToList();