Dbml文件提取建表TSql-CodeSmith

2024-01-02 01:32

本文主要是介绍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 

复制代码

这篇关于Dbml文件提取建表TSql-CodeSmith的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/561008

相关文章

ROS - C++实现RosBag包回放/提取

文章目录 1. 回放原理2. 回放/提取 多个话题3. 回放/提取数据包,并实时发布 1. 回放原理 #include <ros/ros.h>#include <rosbag/bag.h>#include <std_msgs/String.h>int main(int argc, char** argv){// 初始化ROS节点ros::init(argc, argv,

HalconDotNet中的图像特征与提取详解

文章目录 简介一、边缘特征提取二、角点特征提取三、区域特征提取四、纹理特征提取五、形状特征提取 简介   图像特征提取是图像处理中的一个重要步骤,用于从图像中提取有意义的特征,以便进行进一步的分析和处理。HalconDotNet提供了多种图像特征提取方法,每种方法都有其特定的应用场景和优缺点。 一、边缘特征提取   边缘特征提取是图像处理中最基本的特征提取方法之一,通过检

如何根据相同分隔符提取间隔数据?

最近遇到很多提问怎么提取字符的,而这些问题都有一个相同的特征,就是要提取的内容与内容之间,都有着相同的分隔符。当然,这种问题直接用“数据” →  “分列”功能就可以一步到位实现的,但有人喜欢折腾,而更多的人又非得指定函数公式的方法,或者更多的是要保持数据的同步性。   下面,我们就来讲讲用函数公式应该怎么实现这个提取,首先来个数据和要求,如下图,将 - 号间隔的内容依次提取到右边单元格内:

Java8特性:分组、提取字段、去重、过滤、差集、交集

总结下自己使用过的特性 将对象集合根据某个字段分组 //根据id分组Map<String, List<Bean>> newMap = successCf.stream().collect(Collectors.groupingBy(b -> b.getId().trim())); 获取对象集合里面的某个字段的集合 List<Bean> list = new ArrayList<>

OpenCV结构分析与形状描述符(10)检测并提取轮廓函数findContours()的使用

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C++11 算法描述 在二值图像中查找轮廓。 该函数使用算法 253从二值图像中检索轮廓。轮廓是有用的工具,可用于形状分析和对象检测与识别。参见 OpenCV 示例目录中的 squares.cpp。 findContours 是 OpenCV 库中的一个重要函数

【python 走进pytotch】pytorch实现用Resnet提取特征

无意中发现了一个巨牛的人工智能教程,忍不住分享一下给大家。教程不仅是零基础,通俗易懂, 而且非常风趣幽默,像看小说一样!觉得太牛了,所以分享给大家。点这里可以跳转到教程。人工智能教程 准备一张图片,pytorch可以方便地实现用预训练的网络提取特征。 下面我们用pytorch提取图片采用预训练网络resnet50,提取图片特征。 # -*- coding: utf-8 -*-import os

mhtml图片提取 百度图片下载

如果你需要找一些图片,可以先去百度一下,待相关网页加载完成后,点击保存,即可得到一个mhtml文件。这个文件里的图片会用base64进行存储,只需要找到他们并转化就可以。目前在美篇之类的网站上效果还一般,需要继续排查问题。 效果 代码 大概分为提取所有base64、转化为图片两步。 import base64from io import BytesIOfrom PIL import

python转换并提取pdf文件中的图片

#安装fitz包pip install pymupdf 脚本如下所示: import fitzimport reimport osimport timeimport sysarguments = sys.argvfor arg in arguments:print(arg)def file_name_list(base_dir):for i, j, k in os.walk(b

如何提取JKS文件的证书和私钥?

文章来源 https://jingyan.baidu.com/article/066074d61de50cc3c21cb0ba.html 验证命令如下: > 生成证书文件:keytool -genkey -alias server_cert -keypass 12345678 -keyalg RSA -keysize 1024 -validity 365-keystore

knime和Python两种解法提取斜杠(/)或反斜杠(\)分隔前后数据

有如下数据,需要对数据处理,输出客户需要的效果。 数据样例:👇 客户想要的效果: 解决办法: 链接: knime和Python两种方式解法提取斜杠(/)或反斜杠(\)分隔前后数据 今天的分享就到这里了。有收获的小伙伴,记得点赞、收藏、分享哦! 如果您对本次分享的内容感兴趣的话,记得关注关注哦!不然下次找不到喽! 关注不迷路哦! “好记性不如烂笔头”,IT小本本 —— 记录I