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,一经查实,立即删除!

相关文章

【转】新思想、新技术、新架构——更好更快的开发现代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…

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

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

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

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

工作篇-佛山三水恒大-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;于是特地找了一本…

SharePoint Desiger编辑模板时提示“服务器错误,拒绝访问”的解决之道

这篇文件已被微软收藏。http://technet.microsoft.com/zh-cn/ff683721.aspx各位同志好&#xff0c;很多同志都用过SharePoint designer来编辑模板。经常出现“服务器错误&#xff0c;拒绝访问”。场景描述&#xff1a;我们办公电脑是XP系统。XP系统我们是用自己的域用户名密码登…

CCIE理论-第六篇-SD-WAN网络(一)

** CCIE理论-第六篇-SD-WAN网络 ** 1.SD-WAN介绍 1.什么是SD-WAN SD-WAN Software Defined 软件定义WANWide Area Network 广域网外网通俗的说企业网关可以慢慢的代替传统组网(大趋势)主要作用,省钱,简单,智能.易管理 传统方式 -Internet专线 (固定IP上下行带宽对等) -PPPOE …

【转】TFS测试管理

微软2010年发布的Visual Studio 2010或Visual Studio Test Professional 2010包含一个称为 Microsoft 测试管理器的新应用程序&#xff0c;用于帮助您使用测试计划来定义和管理测试工作。 Microsoft 测试管理器通过Team Foundation Server 集成&#xff0c;使您可以方便地进行测…

CCNA-网络常用工具介绍篇

链接&#xff1a;https://pan.baidu.com/s/1Mo3B9LR6YF4YfzSkMwn5OA 提取码&#xff1a;7dc7 这是免费提供滴工具,虽然其实都能用到,不过也就发发了. 第一个呢是EVE,是基于VM下的,就是模拟器来的.里面有ova直接拉进去vm里面开机就可以使用了.前面好像也发过 第二个是ENSP,是华…

敏捷项目管理过程改进

一、为什么敏捷&#xff1f; 目前大环境智慧城市、人工智能、大数据&#xff0c;面向To B的业务等&#xff0c;在要求产品管理需要快速的需求响应&#xff0c;项目管理需要更强的整合协调。复杂的大环境&#xff0c;就在推动我们用最敏捷的方式迎接这个多变的市场。 二、传统和…

CCNA-第六篇-静态路由+动态路由开头

** CCNA-第六篇-静态路由动态路由 ** 一,路由概念 什么是路由? 路由呢,应该说是除了IP以外在网络世界中最重要的东西了 万物互联,互联网,都是基于路由的,前期的啥静态动态,后期的MPLS,包括看到的VPN,虚拟专线等.都是基于路由的,就是像建房子那样,你最得把地基打好才能做其…

【转】敏捷开发,你真的做对了吗?

缘起 2017年3月&#xff0c;应移动事业群智能营销平台项目管理部负责人邀请&#xff0c;我开始支持智能营销平台CRM团队。智能营销平台是阿里文娱广告团队&#xff0c;是阿里巴巴淘外变现的主力军。CRM团队负责开发和维护CRM系统。CRM系统服务于销售和代理商&#xff0c;串起商…

CCNA-第七篇-思科私有路由协议-EIGRP-初级

CCNA-第七篇-思科私有路由协议-EIGRP 首先呢这个EIGRP之前呢, 路由协议是分几种的 一个叫距离向量协议RIP,IGRP(都过时了) 一个觉链路状态协议OSPF,IS-IS这些 还有个叫混合型的EIGRP 但是呢,这些只是书本上的定义,实际上没人会跟你说这个东东 这个怎么区分呢? 第一个呢,只传递…