雖然說專案使用 Entity Framework 之後會比較少在程式中去下 SQL Command 做資料存取的執行,
但有時候還是免不了會有這樣需要的時候,如果說是少數幾個 Entity 才會去執行 SQL Command 的需求時,
其實會偷懶一下,直接就把整條 SQL Command 給寫死在程式當中,
但如果有些功能是屬於通用的時候,這種時候就不太可能把 SQL Command 給寫死,
如果是用字串的方式將每個 Entity 所對應的 TableName 給寫死,這樣的方式又顯得不夠聰明,
所以比較好一點的方式就是經由 Entity Framework 去動態取得 TableName。
資料庫 - MS SQL Server
在資料庫是使用 MS SQL Server 的情況下,可以使用以下的方式來取得 Entity 所對應的 TableName:
(這是在 LINQPad 所執行的結果)
如果是在 VS2010 的專案程式中使用,就會是以下的方式:
資料庫 - Oracle
如果資料庫是使用 Oracle 的話,那麼程式的部份就要去改變一下,
因為使用 Context.CreateObjectSet<T> 所產生的 SQL Command 會有所不同,
所以對 SQL Command 中的 TableName 分析的正則式就要做改變,
原本資料庫使用 MS SQL Server 是要用:
而資料庫使用 Oracle 就必須改為:Regex regex = new Regex("FROM (?<table>.*) AS");
Regex regex = new Regex("FROM \"(?<schema>.*)\".\"(?<table>.*)\\\s);
接著看看在 VS2010 的專案程式中的使用:
抽出方法以重複使用
目前我專案會使用到的資料庫只有兩種:MS SQL Server, Oracle,所以就把上面取得 TableName 的方法給抽出來,
並且用列舉的方式來限定使用者可以選擇的資料庫種類,Method 中就只會對這兩個資料庫來做不同的判斷以決定正則式要用哪一種,
public class ContextExtensions{#region -- GetTableName --/// <summary>
/// Gets the name of the table.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="context">The context.</param>
/// <param name="dbType">Type of the db.</param>
/// <returns></returns>
public static string GetTableName<T>(ObjectContext context, DataBaseType dbType = DataBaseType.MS_SQL_SERVER) where T : class{string sql = context.CreateObjectSet<T>().ToTraceString();
string matchWords = string.Empty;switch (dbType)
{case DataBaseType.MS_SQL_SERVER:
matchWords = "FROM (?<table>.*) AS";
break;
case DataBaseType.Oracle:
matchWords = "FROM \"(?<schema>.*)\".\"(?<table>.*)\"\\s";
break;
}Regex regex = new Regex(matchWords);
Match match = regex.Match(sql);string table = match.Groups["table"].Value;return table;
}#endregionpublic enum DataBaseType{MS_SQL_SERVER = 0,Oracle = 1}
MS SQL Server 資料庫下的使用方式:
Oracle 資料庫下的使用方式:
簡單的小應用,提供給大家參考。
參考資料
The Code Project - Entity Framework: Get mapped table name from an entity
By Rui Jarimba
以上
沒有留言:
張貼留言