2012-01-17 28 views
8

TLDR;如何在編譯時不知道表名時使用Entity Framework從表中讀取數據?使用實體框架從動態創建的表中查詢數據

有一個外部系統處理大量信息,然後爲每個批次運行創建一個新表,並在該表中存儲一些數據。這些新表的列布局是事先知道的,所以我從現有數據庫生成了一個ADO.NET實體數據模型(edmx文件),其中有一個具有完全相同列布局的表。

該數據庫中的原始表格被稱爲ResultTableTemplate,因此表示該表格的實體類別也被稱爲ResultTableTemplate

我想弄清楚如何使用我的ADO.NET實體數據模型從這些動態創建的表中讀取數據,然後返回IEnumerable<ResultTableTemplate>。什麼是迄今爲止我所做的是這樣的:

public IEnumerable<ResultTableTemplate> GetResultsFromTable(string tableName) { 
    using (var context = new WorkdataEntities()) { 
     var table = context.CreateQuery<ResultTableTemplate>("SELECT " + 
      "ALL_THOSE_COLUMN_NAMES... " + 
      "FROM " + tableName; 

     var query = from item in table select item; 

     return query.ToList(); 
    } 
} 

當我運行查詢,我得到了以下消息System.Data.EntitySqlException

「ResultTable419828」無法在當前範圍或 解決上下文。確保所有引用的變量都在範圍內,需要加載 模式,並且該名稱空間正確引用 。近成員訪問表示,1號線,列225

ResultTable419828是我試圖tableName + " AS ResultTableTemplate",但它並沒有幫助的tableName

值。

我有沒有前進的方向,還是必須在沒有Entity Framework的幫助下做到這一點?

編輯:我現在是我寫的查詢文本不向下傳遞到底層的SQL Server實例的所有方法,但得到由實體框架返回一個ObjectQuery<ResultTableTemplate>實例解釋明白,所以中查找ResultTable419828 Context的自動生成的DbSet實例。

不過,有沒有辦法讓我做到我需要做的事情?

編輯:謝謝Ladislav Mrnka。現在,我這樣做:

public IEnumerable<ResultTableTemplate> GetResultsFromTable(string tableName) { 
    using (var context = new WorkdataEntities()) { 
     var query = context.ExecuteStoreQuery<ResultTableTemplate>("SELECT " + 
      "ALL_THOSE_COLUMN_NAMES... " + 
      "FROM " + tableName; 

     return query.ToList(); 
    } 
} 
+1

我認爲這是創建一個EntityQuery,而不是數據庫查詢。因此,FROM是DbSet而不是數據庫表。 – cadrell0 2012-01-17 15:11:40

+0

'CreateQuery ()'返回一個'ObjectQuery ' - 我現在看到你的是正確的。查詢不是針對數據庫表,而是針對DbSet。你認爲有什麼方法可以做我需要做的嗎? – 2012-01-17 15:14:28

+0

我們使用DbConnection和SqlQuery 從數據庫中獲取標量值。我沒有編寫DAL的那部分內容,所以我不完全確定它的工作原理,但是您可以從那裏開始。 – cadrell0 2012-01-17 15:18:16

回答

11

這不是直接可能的。當您將實體映射到ResultTableTemplate時,您可以硬編碼該實體的表格名稱。實體只能一次(每個型號),所以在運行時每個EF查詢該實體始終會導致查詢ResultTableTemplate表映射。

改變的行爲改變在運行時映射文件(SSDL)這是相當醜陋的黑客攻擊,因爲它需要你改變XML文件,並重新加載它的唯一途徑。每次更改文件時,都必須手動構建MetadataWorkspace。建築物MetadataWorkspace是EF中性能最高的操作之一。在正常運行中,每個應用程序運行僅創建一次MetadataWorkspace

有一個簡單的解決方法。你知道表名,你知道表結構 - 它是固定的。因此,使用直接的SQL和使用EF的結果物化到您的映射實體類:

var table = context.ExecuteStoreQuery<ResultTableTemplate>("SELECT ... FROM " + tableName); 

的缺點是,你不能在這種方法中使用Linq,但你的要求不是非常適合於EF。

0

試試這個; :)

string tableName = "MyTableTest"; 

// Fetch the table records dynamically 
var tableData = ctx.GetType() 
       .GetProperty(tableName) 
       .GetValue(ctx, null); 
+1

你能證明你如何查詢表格嗎? – Talon 2017-01-20 10:07:01