LINQTOSQL动态修改表名称的实现浅析

LINQ TO SQL动态修改表名称的实现是如何的呢?我们在实际的操作过程中如何实现呢?需要注意什么呢?那么这里向你详细说明一下,希望对你有所帮助。

网站制作、成都网站建设过程中,需要针对客户的行业特点、产品特性、目标受众和市场情况进行定位分析,以确定网站的风格、色彩、版式、交互等方面的设计方向。成都创新互联还需要根据客户的需求进行功能模块的开发和设计,包括内容管理、前台展示、用户权限管理、数据统计和安全保护等功能。

LINQ TO SQL动态修改表名称的操作:

最近有点空闲时间,抽空看了一下LINQ方面的东西。好在园子里这方面的系列文章很多. 免去了不少查找的时间. 因为本人习惯于学完就动手尝试,而我们的产品中也都将访问数据库的SQL语句统一封装进了DLL.所以就想先拿产品练一下手:)

但万事开头难,一用上才发现有一个不大不小的问题挡在了面前.就是使用LINQ TO SQL模板生成代码后,会在相应的数据库实体类上绑定一个tablename属性.如下代码:

 
 
 
  1. [Table(Name="dbo.dnt_users")]
  2. public partial class Userinfo : 
  3. INotifyPropertyChanging, 
  4. INotifyPropertyChanged
  5. {

dnt_users是数据库中的物理表.而我们的产品有一个特性,就是允许用户定制表名称的前缀.其实"dnt_"就是表的前缀名.而这个值(前缀)是通过产品中的Tableprefix属性获取的.Tableprefix属性返回的值是通过dnt.config中配置的.

所以这就要求在程序运行时动态加载表(前缀)名称.所在本人在网上开始四处找这方面的文章和资料.但找到的并不是特别对症。因为才自己动手实验一下,看看有什么好方法:)

LINQ TO SQL动态修改表名称尝试1:

通过常量方式将表属性[Table(Name="dbo.dnt_users")]替换成:

 
 
 
  1. [Table(Name="dbo." + DntDataContext.tableprefix +"users")]

而tabalprefix定义如下:

 
 
 
  1. public const string tableprefix = "dnt_";
  2. [System.Data.Linq.Mapping.
  3. DatabaseAttribute(Name="dnt_2")]
  4. public partial class DntDataContext : 
  5. System.Data.Linq.DataContext
  6. {
  7. public const string tableprefix = "dnt_";
  8. }

虽然这种方式将前台的名称抽取出来,将因为是采用常量方式,所以无法进行动态绑定.所以这次尝试是失败的.

LINQ TO SQL动态修改表名称尝试2:

替换DataContext生成的CommandText内容因为LINQ TO SQL最终还是被翻译成SQL,所以本人又使用下面的方法进行测试:

 
 
 
  1. DntDataContext ddc = new DntDataContext();
  2. var exp = from u in ddc.Userinfo
  3. orderby u.uid ascending
  4. select u
  5. string query = 
  6. ddc.GetCommand(exp).CommandText.Replace("dnt_", "daizhj_");
  7. var result = ddc.ExecuteQuery(query, 0);
  8. Console.WriteLine(((Userinfo[]) 
  9. result.ToArray())[0].username);

上面代码段的ddc.GetCommand(exp).CommandText.Replace("dnt_", "daizhj_")是做的这个工作.虽然这次采用替换方式解决了问题.但看了代码的朋友会发现,代码变得很丑,本人也是这么看的.即使封装了也是很难受.没办法,放弃:(

LINQ TO SQL动态修改表名称尝试3: 继承并实现IQuerable接口

好在Matt Warren在他的文章中提到过如果建立一个IQueryable Provider(已修改, 更多内容参见这里).另外LoveCherry也将这篇文章翻译了过来,大家有兴趣不妨看一下,很有意思,  详情点击这里:)

所以本人就直接使用了他在文中所说的方式.将DNTDataContext做了修改如下:

 
 
 
  1. [System.Data.Linq.Mapping.DatabaseAttribute(Name="dnt_2")]
  2. public partial class DntDataContext : 
  3. System.Data.Linq.DataContext
  4. {
  5. public Query Userinfos; 
  6. //该Query继承自IQueryable
  7. public DntDataContext(System.Data.IDbConnection connection) :
  8. base(connection, mappingSource)
  9.  {
  10. QueryProvider provider = 
  11. new DbQueryProvider((DbConnection)connection);
  12. this.Userinfos = new Query(provider);
  13.  }
  14. }

前端使用代码如下:

 
 
 
  1. using (SqlConnection con = 
  2. new SqlConnection(global::Demo.Properties.
  3. Settings.Default.dnt_2ConnectionString))
  4. {
  5.  con.Open();
  6.  DntDataContext ddc = new DntDataContext(con);
  7.  IQueryable query = from u in ddc.Userinfos
  8. where (u.uid > 1)
  9. select u;
  10.  foreach (Userinfo user in query.ToArray())
  11.  {
  12. Console.WriteLine(user.username);
  13.  }
  14.  Console.ReadLine();
  15. }

当然数据库链接对象可以封装到DntDataContext中,让代码的整体感觉更LINQ一些.相关的代码下载会在本文结尾处给出,详见LINQ.KIT代码中DbQueryProvider.cs文件.(相关修改已通过注释给出).

这次改动整体上能够满足查询上的需求,但是如果想使用相应的insert,update,delete也能做到相应的表名替换的话,还是要从System.Data.Linq.Table入手.即让

 
 
 
  1. using (SqlConnection con = new SqlConnection(
  2. global::Demo.Properties.Settings.
  3. Default.dnt_2ConnectionString))
  4. {
  5.  con.Open();
  6.  DntDataContext ddc = new DntDataContext(con);
  7.  IQueryable query = from u in ddc.Userinfos
  8. where (u.uid > 1)
  9. select u;
  10.  foreach (Userinfo user in query)
  11.  {
  12. Console.WriteLine(user.username);
  13.  }
  14.  Console.ReadLine();
  15. }

返回的Userinfo类所绑定的表是被替换完成的表名称. 因为本人时间和精力有限,无法再去做进一步的研究了.但老赵的这篇文章给了我一些启发.其中下面的代码段就是他用来扩展DELETE功能的方法

 
 
 
  1.  public static int Delete
  2. (this Table table, 
  3. Expression> predicate)
  4. where TEntity : class
  5.  {
  6. string tableName = 
  7. table.Context.Mapping.GetTable(
  8. typeof(TEntity)).TableName;
  9. string command = String.Format(
  10. "DELETE FROM {0}", tableName);
  11. ConditionBuilder conditionBuilder = 
  12. new ConditionBuilder();
  13. conditionBuilder.Build(predicate.Body);
  14. if (!String.IsNullOrEmpty(
  15. conditionBuilder.Condition))
  16. {
  17.  command += " WHERE " + conditionBuilder.Condition;
  18. }
  19. return table.Context.ExecuteCommand(
  20. command, conditionBuilder.Arguments);
  21. }

我想应该可以在这里完成相应的表名称的替换,实现起来也很容易.经过这一番折腾,我发现如果LINQ TO SQL 支持通过XML配置文件进行绑定才是最终的理想方案.因为本人又开始四处搜索这方面的信息,发现了这篇文章:)原来还真有,只是自己刚入门心急不知道,所以才兜了这么一大圈.看来以后还要认真耐心看文档和相应的方法提示了, 好在这种低级错误也不是犯过一次两次了:)

LINQ TO SQL动态修改表名称的实现基本内容就向你介绍到这里,希望对你了解和学习使用LINQ TO SQL动态修改表名称有所帮助。

文章名称:LINQTOSQL动态修改表名称的实现浅析
当前链接:http://www.shufengxianlan.com/qtweb/news46/227396.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联