您好,登錄后才能下訂單哦!
LINQ中怎么動態(tài)修改表名稱,針對這個問題,這篇文章詳細介紹了相對應(yīng)的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。
LINQ TO SQL動態(tài)修改表名稱的操作:
最近有點空閑時間,抽空看了一下LINQ方面的東西。好在園子里這方面的系列文章很多. 免去了不少查找的時間. 因為本人習(xí)慣于學(xué)完就動手嘗試,而我們的產(chǎn)品中也都將訪問數(shù)據(jù)庫的SQL語句統(tǒng)一封裝進了DLL.所以就想先拿產(chǎn)品練一下手:)
但萬事開頭難,一用上才發(fā)現(xiàn)有一個不大不小的問題擋在了面前.就是使用LINQ TO SQL模板生成代碼后,會在相應(yīng)的數(shù)據(jù)庫實體類上綁定一個tablename屬性.如下代碼:
[Table(Name="dbo.dnt_users")] public partial class Userinfo : INotifyPropertyChanging, INotifyPropertyChanged {
dnt_users是數(shù)據(jù)庫中的物理表.而我們的產(chǎn)品有一個特性,就是允許用戶定制表名稱的前綴.其實"dnt_"就是表的前綴名.而這個值(前綴)是通過產(chǎn)品中的Tableprefix屬性獲取的.Tableprefix屬性返回的值是通過dnt.config中配置的.
所以這就要求在程序運行時動態(tài)加載表(前綴)名稱.所在本人在網(wǎng)上開始四處找這方面的文章和資料.但找到的并不是特別對癥。因為才自己動手實驗一下,看看有什么好方法:)
LINQ TO SQL動態(tài)修改表名稱嘗試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_"; }
雖然這種方式將前臺的名稱抽取出來,將因為是采用常量方式,所以無法進行動態(tài)綁定.所以這次嘗試是失敗的.
LINQ TO SQL動態(tài)修改表名稱嘗試2:
替換DataContext生成的CommandText內(nèi)容因為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_")是做的這個工作.雖然這次采用替換方式解決了問題.但看了代碼的朋友會發(fā)現(xiàn),代碼變得很丑,本人也是這么看的.即使封裝了也是很難受.沒辦法,放棄:(
LINQ TO SQL動態(tài)修改表名稱嘗試3: 繼承并實現(xiàn)IQuerable接口
好在Matt Warren在他的文章中提到過如果建立一個IQueryable Provider(已修改, 更多內(nèi)容參見這里).另外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(); }
當(dāng)然數(shù)據(jù)庫鏈接對象可以封裝到DntDataContext中,讓代碼的整體感覺更LINQ一些.相關(guān)的代碼下載會在本文結(jié)尾處給出,詳見LINQ.KIT代碼中DbQueryProvider.cs文件.(相關(guān)修改已通過注釋給出).
這次改動整體上能夠滿足查詢上的需求,但是如果想使用相應(yīng)的insert,update,delete也能做到相應(yīng)的表名替換的話,還是要從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類所綁定的表是被替換完成的表名稱. 因為本人時間和精力有限,無法再去做進一步的研究了.但老趙的這篇文章給了我一些啟發(fā).其中下面的代碼段就是他用來擴展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); }
關(guān)于LINQ中怎么動態(tài)修改表名稱問題的解答就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注億速云行業(yè)資訊頻道了解更多相關(guān)知識。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。