2012年4月2日 星期一

動態取得 Entity Framework 中 Entity 對應的 TableName


雖然說專案使用 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 所執行的結果)

image

如果是在 VS2010 的專案程式中使用,就會是以下的方式:

image

 

 

資料庫 - Oracle

如果資料庫是使用 Oracle 的話,那麼程式的部份就要去改變一下,

因為使用 Context.CreateObjectSet<T> 所產生的 SQL Command 會有所不同,

所以對 SQL Command 中的 TableName 分析的正則式就要做改變,

image

原本資料庫使用 MS SQL Server 是要用:

Regex regex = new Regex("FROM (?<table>.*) AS");
而資料庫使用 Oracle 就必須改為:
Regex regex = new Regex("FROM \"(?<schema>.*)\".\"(?<table>.*)\\\s);

 

接著看看在 VS2010 的專案程式中的使用:

image

 

 

抽出方法以重複使用

目前我專案會使用到的資料庫只有兩種: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;
        }
        #endregion
        public enum DataBaseType
        {
            MS_SQL_SERVER = 0,
            Oracle = 1
        }

 

MS SQL Server 資料庫下的使用方式:

image

 

Oracle 資料庫下的使用方式:

image

 

簡單的小應用,提供給大家參考。

 

 

參考資料

The Code Project - Entity Framework: Get mapped table name from an entity

By Rui Jarimba

 

 

以上

沒有留言:

張貼留言

提醒

千萬不要使用 Google Talk (Hangouts) 或 Facebook 及時通訊與我聯繫、提問,因為會掉訊息甚至我是過了好幾天之後才發現到你曾經傳給我訊息過,請多多使用「詢問與建議」(在左邊,就在左邊),另外比較深入的問題討論,或是有牽涉到你實作程式碼的內容,不適合在留言板裡留言討論,請務必使用「詢問與建議」功能(可以夾帶檔案),謝謝。