Dbml文件提取建表TSql-CodeSmith

     在昨天一个大学师弟,他问我能不能将LinqToSql文件转化为创建表的TSql语句,他是刚开始学习.NET,所以在网上下些示例看,但苦于没有数据库。所以就有了这一篇博客,作为我的Code生成技术的CodeSimth的最后一篇示例。在下一步Code 生成技术将转到Microsoft的T4模板,Code生成技术目前完成的有CodeDom,CodeSmith模板,高手请不要拍砖,请直接跳过。

     在Linq2Sql的Dbml文件其实就是一个Xml文件,记录着数据库与生成Linq2SqlCode的数据信息,所以转化为TSql没有什么说的。我们需要提取其中的数据库信息,在转化为我们的Tsql,在这里建立了DBTable、DBColumn、DBAssociation三个实体类:

复制代码

  1 using System; 
  2 using System.Collections.Generic; 
  3 using System.Linq; 
  4 using System.Text; 
  5 
  6 namespace DbmlToTable 
  7 { 
  8     public class DBTable 
  9     { 
 10 
 11         public DBTable() 
 12         { 
 13             Columns = new List<DBColumn>(); 
 14             this.Associations = new List<DBAssociation>(); 
 15         } 
 16 
 17         public string TableName 
 18         { 
 19             get; 
 20             set; 
 21         } 
 22 
 23         public List<DBColumn> Columns 
 24         { 
 25             get; 
 26             set; 
 27         } 
 28 
 29         public List<DBAssociation> Associations 
 30         { 
 31             get; 
 32             set; 
 33         } 
 34 
 35     } 
 36 
 37     public class DBColumn 
 38     { 
 39         public string Name 
 40         { 
 41             get; 
 42             set; 
 43         } 
 44 
 45         public string DBType 
 46         { 
 47             get; 
 48             set; 
 49         } 
 50 
 51         public bool IsPrimaryKey 
 52         { 
 53             get; 
 54             set; 
 55         } 
 56 
 57         public bool IsDbGenerated 
 58         { 
 59             get; 
 60             set; 
 61         } 
 62 
 63         public bool CanBeNull 
 64         { 
 65             get; 
 66             set; 
 67         } 
 68     } 
 69 
 70     public class DBAssociation 
 71     { 
 72         public string Name 
 73         { 
 74             get; 
 75             set; 
 76         } 
 77 
 78         public string ThisKey 
 79         { 
 80             get; 
 81             set; 
 82         } 
 83 
 84         public string OtherKey 
 85         { 
 86             get; 
 87             set; 
 88         } 
 89 
 90         public bool IsForeignKey 
 91         { 
 92             get; 
 93             set; 
 94         } 
 95     } 
 96 
 97     public class DBTableHlper 
 98     { 
 99         public static DBTable GetAssociationTable(List<DBTable> collection,string assName) 
100         { 
101 
102             return collection.Find(t => t.Associations.Find(a => !a.IsForeignKey && a.Name == assName) != null); 
103         } 
104     } 
105 }
106 
107 

复制代码

    其中DBTableHlper是由于我的Codesimth是2.0版本的,不能用lamdam表达式,所以我将它编译在程序集里面。

   建立了一个 将我们的dbml文件xml Document转化为实体类辅助类:

复制代码

 1 using System; 
 2 using System.Collections.Generic; 
 3 using System.Linq; 
 4 using System.Text; 
 5 using System.Xml; 
 6 using System.Xml.Linq; 
 7 
 8 namespace DbmlToTable 
 9 { 
10 
11     public interface IDbTableCollectionHelper 
12     { 
13         List<DBTable> Transport(XElement element); 
14     } 
15 
16     public class DbTableCollectionHelper : IDbTableCollectionHelper 
17     { 
18         #region IDbTableCollectionHelper 成员 
19 
20         public List<DBTable> Transport(XElement element) 
21         { 
22             List<DBTable> collection = new List<DBTable>(); 
23             var tables = element.Elements(XName.Get("Table", "http://schemas.microsoft.com/linqtosql/dbml/2007%22)); 
24             foreach (var tab in tables) 
25             { 
26                 DBTable t = new DBTable() { TableName = tab.Attribute("Name").Value }; 
27                 var cols = tab.Element(XName.Get("Type", "http://schemas.microsoft.com/linqtosql/dbml/2007%22)).Elements(XName.Get(%22Column%22, "http://schemas.microsoft.com/linqtosql/dbml/2007%22)); 
28                 foreach (var col in cols) 
29                 { 
30                     DBColumn c = new DBColumn() 
31                     { 
32                         CanBeNull = col.Attribute("CanBeNull") != null ? col.Attribute("CanBeNull").Value.ToLower() == "true" : false, 
33                         DBType = col.Attribute("DbType") != null ? col.Attribute("DbType").Value : "", 
34                         IsDbGenerated = col.Attribute("IsDbGenerated") != null ? col.Attribute("IsDbGenerated").Value.ToLower() == "true" : false, 
35                         IsPrimaryKey = col.Attribute("IsPrimaryKey") != null ? col.Attribute("IsPrimaryKey").Value.ToLower() == "true" : false, 
36                         Name = col.Attribute("Name") != null ? col.Attribute("Name").Value : "" 
37                     }; 
38                     t.Columns.Add(c); 
39                 } 
40 
41                 var ass = tab.Element(XName.Get("Type", "http://schemas.microsoft.com/linqtosql/dbml/2007%22)).Elements(XName.Get(%22Association%22, "http://schemas.microsoft.com/linqtosql/dbml/2007%22)); 
42                 foreach (var item in ass) 
43                 { 
44                     DBAssociation a = new DBAssociation() 
45                     { 
46                         Name = item.Attribute("Name") != null ? item.Attribute("Name").Value : "", 
47                         OtherKey = item.Attribute("OtherKey") != null ? item.Attribute("OtherKey").Value : "", 
48                         ThisKey = item.Attribute("ThisKey") != null ? item.Attribute("ThisKey").Value : "", 
49                         IsForeignKey = item.Attribute("IsForeignKey") != null ? item.Attribute("IsForeignKey").Value.ToLower() == "true" : false 
50                     }; 
51                     t.Associations.Add(a); 
52                 } 
53                 collection.Add(t); 
54             } 
55             return collection; 
56         } 
57 
58         #endregion 
59     } 
60 }
61 
62 

复制代码

   在转化为我们的实体类,我们剩下的就是编写我们的CodeSmith模板了(更多知识可以参考CodeSmith模板):

复制代码

 1 <%@ CodeTemplate Language="C#" TargetLanguage="Text" Src="" Inherits="" Debug="False" Description="Template description here." %> 
 2 
 3 <%@ Import NameSpace="System" %> 
 4 <%@ Import NameSpace="System.Xml" %> 
 5 <%@ Import NameSpace="System.Text" %> 
 6 <%@ Import NameSpace="System.Collections.Generic" %> 
 7 <%@ Assembly Name="DbmlToTable" %> 
 8 
 9 --Code By Wolf 
10 <script runat="template"> 
11 private List<DbmlToTable.DBTable> _DbTableCollection; 
12 public List<DbmlToTable.DBTable> DbTableCollection 
13 { 
14     get 
15     { 
16         return _DbTableCollection; 
17     } 
18     set    
19     { 
20         _DbTableCollection=value; 
21     } 
22 } 
23 
24 public  string GeneratorTableSql(List<DbmlToTable.DBTable> collection) 
25 { 
26     StringBuilder sb = new StringBuilder(); 
27     StringBuilder sbAssocation = new StringBuilder(); 
28     foreach (DbmlToTable.DBTable item in collection) 
29     { 
30         List<string> cols = new List<string>(); 
31         foreach (DbmlToTable.DBColumn  col in item.Columns) 
32         { 
33             cols.Add(string.Format("{0} {1} {2} ", col.Name, col.DBType, col.IsPrimaryKey ? "PRIMARY KEY " : "")); 
34         } 
35         sb.AppendFormat("\r\nCREATE TABLE {0} \r\n(\r\n{1}\r\n)", item.TableName, string.Join(",\r\n", cols.ToArray())); 
36 
37         foreach (DbmlToTable.DBAssociation ass in item.Associations) 
38         { 
39             if (ass.IsForeignKey) 
40             { 
41                 DbmlToTable.DBTable tab = DbmlToTable.DBTableHlper.GetAssociationTable(collection,ass.Name); 
42                 if (tab != null) 
43                 { 
44                     sbAssocation.AppendLine(); 
45                     sbAssocation.AppendFormat(@"ALTER TABLE {0}  WITH NOCHECK ADD  CONSTRAINT {1} FOREIGN KEY({2}) REFERENCES {3} ({4})", 
46                         item.TableName, "FK_" + ass.Name, ass.ThisKey, tab.TableName, ass.OtherKey); 
47                 } 
48             } 
49         } 
50     } 
51 
52     return sb.ToString() + "\r\n" + sbAssocation.ToString(); 
53 } 
54 </script> 
55 <%= this.GeneratorTableSql(_DbTableCollection) %>
56 
57 

复制代码

    在codeSimth中我们建立了一个集合属性传递实体类DBTable和一个转化TSql辅助方法.

      在控制台调用编译模板以及输出:

复制代码

 1 using System; 
 2 using System.Collections.Generic; 
 3 using System.Linq; 
 4 using System.Text; 
 5 
 6 namespace DbmlToTable 
 7 { 
 8     class Program 
 9     { 
10         static void Main(string[] args) 
11         { 
12             IDbTableCollectionHelper helper = new DbTableCollectionHelper(); 
13             List<DBTable> collection = helper. 
14                 Transport(System.Xml.Linq.XElement.
15 
16          Load(@"xxpath\MultipleDocument.Data\MultipleDocumentDB.dbml")); 
17 
18             CodeSmith.Engine.CodeTemplate template = CodeSimthTemplateHelper. 
19                 CompileTemplate(@"DBMLToTable.cst", w => Console.WriteLine(w)); 
20             if (template != null) 
21             { 
22                 CodeSimthTemplateHelper.AddPropertyParams(template, new { DbTableCollection = collection }); 
23                 string str = template.RenderToString(); 
24                 Console.WriteLine(str); 
25                 //System.IO.File.AppendAllText(@"D:\1.sql", str); 
26             } 
27             Console.Read(); 
28         }
29 
30 }
31 
32  
33 
34 

复制代码

   在CodeSimth中就是这么简单,生成相应的模板代码(个人理解CodeSmith就是把代码作为字符串输出)。

在上面到我的CodeSmith模板编译辅助类,在上一篇通过代码生成机制实现强类型编程-CodeSmith版也有,在这里也附带上:需要引用CodeSmith.Engine.dll.

复制代码

 1 using System; 
 2 
 3 using System.Collections.Generic; 
 4 
 5 using System.Linq; 
 6 
 7 using System.Text; 
 8 
 9 using CodeSmith.Engine; 
10 
11 using Wolf.NameValueDictionary; 
12 
13 namespace DbmlToTable 
14 
15 { 
16 
17 public class CodeSimthTemplateHelper 
18 
19 { 
20 
21      public static CodeTemplate CompileTemplate(string templateName, Action errorWriter) 
22 
23      { 
24 
25            CodeTemplateCompiler compiler = new CodeTemplateCompiler(templateName); compiler.Compile(); 
26 
27           if (compiler.Errors.Count == 0) 
28 
29            { 
30 
31            return compiler.CreateInstance();
32 
33            } 
34 
35        else 
36 
37          { 
38 
39            for (int i = 0; i < compiler.Errors.Count; i++) 
40 
41         { 
42 
43             errorWriter(compiler.Errors[i].ToString()); 
44 
45          } 
46 
47         return null; 
48 
49        } 
50 
51 } 
52 
53  
54 
55 public static void AddPropertyParams(CodeTemplate template,object param) 
56 
57 { 
58 
59       NameValueDictionary dict = new NameValueDictionary<object>(param);
60 
61        AddPropertyParams(template, dict);
62 
63 }
64 
65  
66 
67 public static void AddPropertyParams(CodeTemplate template, NameValueDictionary<object> param)
68 
69 {
70 
71           NameValueDictionary<object> dict = new NameValueDictionary<object>(param);
72 
73           foreach (var item in dict.Keys)
74 
75           {
76 
77                 template.SetProperty(item, dict[item]);
78 
79            }
80 
81 }
82 
83 }
84 
85 }
86 

复制代码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/439168.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

(译)你应该知道的jQuery技巧

帮助提高你jQuery应用的简单小技巧。 回到顶部按钮图片预加载判断图片是否加载完自动修补破损图像Hover切换class类禁用输入停止正在加载的链接toggle fade/slide简单的手风琴使两个DIV同等高度在浏览器标签/新窗口打开外部链接根据文本获取元素可见变化的触发Ajax调用错误处理…

DNS的A、CNAME、MX、NS、TXT、SPF记录

前言 最近工作过程中需要设定邮件服务器&#xff0c;其中涉及到dns服务器的设定。 整理并且记录自己的理解。 种类 A、CNAME、MX、NS、TXT、SPF 下面挨个介绍一下。 A记录/AAAA记录 IPv4&#xff1a; 示例&#xff1a;ns1.exmaple.com. IN A 198.51.100.2解释&#xff1a…

【转】新思想、新技术、新架构——更好更快的开发现代ASP.NET应用程序(续1)

上周星期天开通了博客并发布了第一篇文章《新思想、新技术、新架构——更好更快的开发现代ASP.NET应用程序》&#xff0c;汇集了一些比较流行的技术和开源项目&#xff0c;也把自己的程序架构、部分代码风格、前端表现简单做了一些展示&#xff0c;引起了近100位朋友的评论。特…

CCNA-Cisco-Packet-Tracerchs(思科官网)安装教程以及使用

Cisco-Packet-Tracerchs 思科官网模拟器&#xff0c;各大高校与中职都在使用。 但是由于支持的命令不太多&#xff0c;适用于NA阶段以及入门阶段的人群使用。 以下是免费百度网盘链接&#xff1a; https://pan.baidu.com/s/136fsYRnAfzGoj0DsQFaYTg 提取码: qa4e 复制这段内容…

CCNA-VLAN讲解与交换机三种端口模式(Acess,Trunk,Hybrid)小白入门级

VLAN讲解与三种端口模式(Acess,Trunk,Hybrid) TAG:所有文章均为原创&#xff0c;可以转载但请声明&#xff0c;是在学校里面做的&#xff0c;使用不了EVE和ENSP&#xff0c;请各路大神嘴下留情&#xff0c;如文章内容有误导请及时联系博主----来自一个17岁的中专生。 1.什么是V…

【转】2015-新思想、新技术、新架构——更好更快的开发现代ASP.NET应用程序

在博客园学习很长时间了&#xff0c;今天终于自己也开通了博客&#xff0c;准备分享一些感悟和经验。首先感谢博客园园主提供了这么好的程序员学习交流平台&#xff0c;也非常感谢张善友、dax.net、netfocus、司徒正美 等技术大牛的无私分享&#xff0c;从他们身上学到了很多。…

工作篇-佛山三水恒大-2020.10.23

** 工作篇-佛山三水恒大-2020.10.23 **人生第一次工作啊啊啊啊啊 其实按道理来说&#xff0c;第一次应该会很很紧张吧&#xff0c;不过我倒没有。 也不知道是我不怕还是什么&#xff0c;一切进行的挺顺利的。 前言&#xff1a;讲真那句&#xff0c;第一次做的话&#xff0c;…

UWP 使用OneDrive云存储2.x api(一)【全网首发】

最近开发人脸识别UWP【微识别 / WeRecognition】用到了OneDrive开发&#xff0c;下面把来龙去脉讲一下。 下载地址 https://www.microsoft.com/store/productId/9PDSNS7X9ST9&#xff0c;商店火爆热销中。。。。。。 由于UWP是跨平台的&#xff0c;一套代码可以运行在所有Wind…

CCNA-第一篇-基础入门概念

** 基础入门概念 **前言 没有什么学习是简单的.任何东西,包括你打游戏(除非是弱智的单机游戏)搞IT,一个月熬熬夜 月薪过X-W的大有人在,早9晚5一个月3K,自己选择.所以看你怎么学,每个人都很忙的,时间都是挤出来的. 一.网络基本概念入门 网络设备调试最基本的概念网络环境设计设…

UWP 使用OneDrive云存储2.x api(二)【全网首发】

上一篇提到为了给用户打造一个完全无缝衔接的最佳体验&#xff0c;UWP开发者最好也要实现App设置和数据的跨平台 分析了数据漫游和OneDrive的优缺点&#xff0c;结合自己App实际需要&#xff0c;我选择了OneDrive。 毕竟数据漫游100KB不够用啊。。。 这一次给大家我千辛万苦找…

CCNA-第二篇-路由器交换机概述

CCNA-第二篇-路由器交换机概述 为什么交换机可以转发&#xff1f; 1.使用MAC地址表 2.MAC地址表怎么来的呢&#xff1f;交换机自动学习 问题来了&#xff1a;PC是如何知道对端的MAC地址的呢&#xff1f; 我们在通信的到时候&#xff0c;不可能问你MAC多少吧&#xff0c;一般都是…

sharepoint当流程流转到某个节点对文档进行水印操作

sharepoint在流程中给文档库中的word或者pdf添加水印。 断断续续的搞了很久。总的解决方案如下&#xff1a; 在流程中&#xff0c;当运行到某步的时候&#xff0c;通过自定义代码调用后台方法&#xff0c;进行相关操作。 针对word的水印操作&#xff1a; 这里就不多说了网上有很…

CCNA-第三篇-OSI模型-上

CCNA-第三篇-OSI模型-上 OSI七层模型-上 第七层 应用层 第六层 表示层 第五层 会话层 第四层 传输层定义数据发送方式 TCP UDP 第三层 网络层ICMP协议,网络设备 第二层 数据链路层交换机 -可以实现定向数据转发(依靠MAC表,自动学习) -如何自动学习:当接口收到数据后,自动记录,记…

在Sharepoint 2010中使用ReportViewer控件展示RDLC报表

微软的Visual studio提供了ReportViewer控件以及RDLC报表设计工具。下文主要介绍如何在Sharepoint 2010项目开发中使用ReportViewer和RDLC生成项目报表。由于Sharepoint 2010默认是禁用Session的&#xff0c;而RDLC报表必须启用Session。因此在Sharepoint的站点中要使用RDLC生成…

CCNA-第四篇-OSI模型-下

CCNA-第四篇-OSI模型-下 这里先来说一下上一期的问题 来一个小问题 当你访问百度的时候,你的最初的目的MAC是谁? 1.二层交换机(接入) 2.出口设备GW(路由器) 3.运营商 TAG:这是个ARP的问题,答案会在下一篇讲解. 答案:答案是在GW设备上的那个接口的MAC,为什么呢?或许有人会问…

RDLC报表下载的权限问题

RDLC作的报表发布后&#xff0c;管理员用户可以正常地将报表以PDF、Excel、Word等格式下载&#xff0c;但是其他用户只能以PDF格式下载&#xff0c;其他两种格式下载的文件都是0字节无内容。 需要在SharePoint前端服务器上进行下列设置&#xff1a; 确定Web Application pool …

工作篇-佛山三水恒大-2020.11.13

** 工作篇-佛山三水恒大-2020.11.14 **TAG:此篇文章估计会很长,因为工作的时候变数太多了,预计五千字左右,想看的可以耐心看完,均为个人实战经验.害,其实是上学期间请假去做的,还挨批了. **到了现场tm的那个机房,小到我哭,站都没地方站,刚装修好全tm都是白灰,我穿的一身黑衣…

Windows Workflow Foundation(WWF)介绍

Windows Workflow Foundation&#xff1a;支持基于工作流的应用程序 工作流是一个简单思路&#xff1a;按照特定顺序执行的一系列步骤。您甚至可以认为每个应用程序都在执行工作流&#xff0c;因为每个应用程序都执行某些过程。但是&#xff0c;在使用 C#、Visual Basic 或其他…

CCNA-第五篇-基础命令集+设备升级+设备破解密码+IP地址{精髓篇}

** CCNA-第五篇-基础命令集 ** 1.基础命令集 思科设备 : IOS 华为设备: VRP 启动步骤&#xff1a;加电自检-加载系统(IOS/VRP&#xff09;-运行配置&#xff08;保留的cfg或者conf文件&#xff09; 命令行统一称为CLI,CLI是啥呢,命令 简介&#xff1a;CLI一般指命令行界面。…

你还记得windows workflow foundation吗

很多年前&#xff0c;windows workflow foundation还叫WWF&#xff0c;而直译过来的名称让很多人以为它就是用来开发工作流或者干脆就是审批流的。 博主当年还是个懵懂的少年&#xff0c;却也知道微软不会大力推一个面向如此具象的业务场景的技术&#xff0c;于是特地找了一本…