您好,登錄后才能下訂單哦!
LINQ中怎么動態修改表名稱,針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。
LINQ TO SQL動態修改表名稱的操作:
最近有點空閑時間,抽空看了一下LINQ方面的東西。好在園子里這方面的系列文章很多. 免去了不少查找的時間. 因為本人習慣于學完就動手嘗試,而我們的產品中也都將訪問數據庫的SQL語句統一封裝進了DLL.所以就想先拿產品練一下手:)
但萬事開頭難,一用上才發現有一個不大不小的問題擋在了面前.就是使用LINQ TO SQL模板生成代碼后,會在相應的數據庫實體類上綁定一個tablename屬性.如下代碼:
[Table(Name="dbo.dnt_users")] public partial class Userinfo : INotifyPropertyChanging, INotifyPropertyChanged {
dnt_users是數據庫中的物理表.而我們的產品有一個特性,就是允許用戶定制表名稱的前綴.其實"dnt_"就是表的前綴名.而這個值(前綴)是通過產品中的Tableprefix屬性獲取的.Tableprefix屬性返回的值是通過dnt.config中配置的.
所以這就要求在程序運行時動態加載表(前綴)名稱.所在本人在網上開始四處找這方面的文章和資料.但找到的并不是特別對癥。因為才自己動手實驗一下,看看有什么好方法:)
LINQ TO SQL動態修改表名稱嘗試1:
通過常量方式將表屬性[Table(Name="dbo.dnt_users")]替換成:
[Table(Name="dbo." + DntDataContext.tableprefix +"users")]
而tabalprefix定義如下:
public const string tableprefix = "dnt_"; [System.Data.Linq.Mapping. DatabaseAttribute(Name="dnt_2")] public partial class DntDataContext : System.Data.Linq.DataContext { public const string tableprefix = "dnt_"; }
雖然這種方式將前臺的名稱抽取出來,將因為是采用常量方式,所以無法進行動態綁定.所以這次嘗試是失敗的.
LINQ TO SQL動態修改表名稱嘗試2:
替換DataContext生成的CommandText內容因為LINQ TO SQL最終還是被翻譯成SQL,所以本人又使用下面的方法進行測試:
DntDataContext ddc = new DntDataContext(); var exp = from u in ddc.Userinfo orderby u.uid ascending select u string query = ddc.GetCommand(exp).CommandText.Replace("dnt_", "daizhj_"); var result = ddc.ExecuteQuery<Userinfo>(query, 0); Console.WriteLine(((Userinfo[]) result.ToArray())[0].username);
上面代碼段的ddc.GetCommand(exp).CommandText.Replace("dnt_", "daizhj_")是做的這個工作.雖然這次采用替換方式解決了問題.但看了代碼的朋友會發現,代碼變得很丑,本人也是這么看的.即使封裝了也是很難受.沒辦法,放棄:(
LINQ TO SQL動態修改表名稱嘗試3: 繼承并實現IQuerable接口
好在Matt Warren在他的文章中提到過如果建立一個IQueryable Provider(已修改, 更多內容參見這里).另外LoveCherry也將這篇文章翻譯了過來,大家有興趣不妨看一下,很有意思, 詳情點擊這里:)
所以本人就直接使用了他在文中所說的方式.將DNTDataContext做了修改如下:
[System.Data.Linq.Mapping.DatabaseAttribute(Name="dnt_2")] public partial class DntDataContext : System.Data.Linq.DataContext { public Query<Userinfo> Userinfos; //該Query繼承自IQueryable public DntDataContext(System.Data.IDbConnection connection) : base(connection, mappingSource) { QueryProvider provider = new DbQueryProvider((DbConnection)connection); this.Userinfos = new Query<Userinfo>(provider); } }
前端使用代碼如下:
using (SqlConnection con = new SqlConnection(global::Demo.Properties. Settings.Default.dnt_2ConnectionString)) { con.Open(); DntDataContext ddc = new DntDataContext(con); IQueryable<Userinfo> query = from u in ddc.Userinfos where (u.uid > 1) select u; foreach (Userinfo user in query.ToArray()) { Console.WriteLine(user.username); } Console.ReadLine(); }
當然數據庫鏈接對象可以封裝到DntDataContext中,讓代碼的整體感覺更LINQ一些.相關的代碼下載會在本文結尾處給出,詳見LINQ.KIT代碼中DbQueryProvider.cs文件.(相關修改已通過注釋給出).
這次改動整體上能夠滿足查詢上的需求,但是如果想使用相應的insert,update,delete也能做到相應的表名替換的話,還是要從System.Data.Linq.Table入手.即讓
using (SqlConnection con = new SqlConnection( global::Demo.Properties.Settings. Default.dnt_2ConnectionString)) { con.Open(); DntDataContext ddc = new DntDataContext(con); IQueryable<Userinfo> query = from u in ddc.Userinfos where (u.uid > 1) select u; foreach (Userinfo user in query) { Console.WriteLine(user.username); } Console.ReadLine(); }
返回的Userinfo類所綁定的表是被替換完成的表名稱. 因為本人時間和精力有限,無法再去做進一步的研究了.但老趙的這篇文章給了我一些啟發.其中下面的代碼段就是他用來擴展DELETE功能的方法
public static int Delete<TEntity> (this Table<TEntity> table, Expression<Func<TEntity, bool>> predicate) where TEntity : class { string tableName = table.Context.Mapping.GetTable( typeof(TEntity)).TableName; string command = String.Format( "DELETE FROM {0}", tableName); ConditionBuilder conditionBuilder = new ConditionBuilder(); conditionBuilder.Build(predicate.Body); if (!String.IsNullOrEmpty( conditionBuilder.Condition)) { command += " WHERE " + conditionBuilder.Condition; } return table.Context.ExecuteCommand( command, conditionBuilder.Arguments); }
關于LINQ中怎么動態修改表名稱問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。