using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using Dapper;
using System.Text.RegularExpressions;
using System.Data.SqlClient;
using System.ComponentModel; namespace CodeFirst
{
class Program
{
static readonly string SchemaName;
static readonly string ConnectionString; static Program()
{
SchemaName = "22TopWeb";
if (string.IsNullOrWhiteSpace(SchemaName))
{
throw new Exception("'SchemaName' load failed");
}
if (new[] { "master", "model", "msdb", "tempdb" }.Contains(SchemaName))
{
throw new Exception("'SchemaName' illegal");
}
ConnectionString = "Data Source=192.168.8.119;User ID=EQCCD_HUNTER;Password=zhey1bu2012;Initial Catalog=master;Pooling=true";
if (string.IsNullOrWhiteSpace(ConnectionString))
{
throw new Exception("'ConnectionString' load failed");
}
var pattern = @"Initial\s*Catalog\s*=\s*master";
Match match = Regex.Match(ConnectionString, pattern, RegexOptions.IgnoreCase);
if (match.Groups.Count > )
{
//可能需要创建数据库
CheckSchema(ConnectionString, SchemaName);
ConnectionString = ConnectionString.Replace(match.Groups[].Value, "Initial Catalog=" + SchemaName);
}
} static void Main(string[] args)
{
var sql = GetTableCreateSql("CodeFirst.TB_Enterprise"); ExcuteSql(ConnectionString, sql.Replace("GO", "")); //GO只能在查询分析器里使用 Console.ReadKey();
} /// <summary>
///
/// </summary>
/// <param name="fullName"></param>
/// <param name="overwrite">如果表已存在,drop后重新创建(true慎用)</param>
/// <returns></returns>
static string GetTableCreateSql(string fullName, bool overwrite = false)
{
var type = Type.GetType(fullName); var columnDefinitionList = GetColumnDefinitionList(type); //数据库 表名
var tableName = type.Name;
var dbTableNameAttr = type.GetCustomAttributes(false).Where(attr => attr.GetType().Name == "DBTableNameAttribute").SingleOrDefault() as
dynamic;
if (dbTableNameAttr != null)
tableName = dbTableNameAttr.Name;
//主键列
var primaryKeyArr = (from clmn in columnDefinitionList where clmn.IsPrimaryKey select clmn.ColumnName).ToArray();
//是否 TEXTIMAGE ON
var isTextImageOn = type.GetCustomAttributes(false).Where(attr => attr.GetType().Name == "TextImageOn").Any(); if (!string.IsNullOrWhiteSpace(tableName) && columnDefinitionList.Count > )
{
var sb = new StringBuilder(); sb.AppendFormat(@"USE [{0}]
GO", SchemaName); if (overwrite)
{
sb.AppendFormat(@" if exists (select 1 from sysobjects where id = object_id('{0}') and type = 'U')
drop table {0}
GO", tableName);
} sb.AppendFormat(@" /****** Object: Table [dbo].[{1}] Script Date: {2} Generate By CodeFrist ******/
SET ANSI_NULLS ON
GO SET QUOTED_IDENTIFIER ON
GO SET ANSI_PADDING ON
GO CREATE TABLE [dbo].[{1}](", SchemaName, tableName, DateTime.Now.ToString("MM/dd/yyyy HH:mm:ss")); columnDefinitionList.ForEach(p =>
{
//组合主键 不能定义 IDENTITY
sb.AppendFormat(@"
[{0}] [{1}]{2} {3} {4},", p.ColumnName, p.DbType, p.MaxLength > ? "(" + p.MaxLength + ")" : "", p.IsPrimaryKey && primaryKeyArr.Length <= ? "IDENTITY(" + p.Seed + "," + p.Incr + ")" : "", p.IsNullable ? "NULL" : "NOT NULL");
}); if (primaryKeyArr != null && primaryKeyArr.Length > )
{
//主键列
sb.AppendFormat(@"
CONSTRAINT [PK_{0}] PRIMARY KEY CLUSTERED
(
{1}
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
", tableName, primaryKeyArr.Aggregate("", (current, cName) => current += string.Format(",[{0}] ASC", cName)).Trim(','));
}
//else //多余的这个逗号可以不去掉 sb.AppendFormat(@"
) ON [PRIMARY] {0} GO SET ANSI_PADDING OFF
GO
", isTextImageOn ? "TEXTIMAGE_ON [PRIMARY]" : ""); columnDefinitionList.Where(p => !string.IsNullOrWhiteSpace(p.Description)).ToList().ForEach(p =>
{
//字段说明
sb.AppendFormat(@"
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'{2}' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'{0}', @level2type=N'COLUMN',@level2name=N'{1}'
GO
", tableName, p.ColumnName, ToSqlLike(p.Description));
}); return sb.ToString(); //这个格式和Management Studio生成的sql内容一致 } return string.Empty;
} /// <summary>
/// 获取所有列定义(此为重点,反射+特性)
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
static List<ColumnDefinition> GetColumnDefinitionList(Type type)
{
var columnDefinitionList = new List<ColumnDefinition>(); var pInfoArr = type.GetProperties(BindingFlags.Instance | BindingFlags.Public);
foreach (PropertyInfo pInfo in pInfoArr)
{
var columnDefinition = new ColumnDefinition() { ColumnName = pInfo.Name }; Console.WriteLine("----------Property Name:{0}-----------", pInfo.Name); foreach (dynamic attr in pInfo.GetCustomAttributes(false))
{
var attributeName = attr.GetType().Name as string; var attributeInfoStr = string.Format("Attribute Name:{0}", attributeName);
switch (attributeName)
{
case "PrimaryKeyAttribute":
columnDefinition.IsPrimaryKey = true;
columnDefinition.Seed = attr.Seed;
columnDefinition.Incr = attr.Incr;
columnDefinition.IsPrimaryKey = true;
Console.WriteLine(attributeInfoStr);
break;
case "DataTypeAttribute":
columnDefinition.DbType = attr.DbType;
columnDefinition.MaxLength = attr.MaxLength;
attributeInfoStr += string.Format("(DbType:{0}{1})", columnDefinition.DbType, columnDefinition.MaxLength > ? ",MaxLength:" + columnDefinition.MaxLength : "");
Console.WriteLine(attributeInfoStr);
break;
case "IsNullableAttribute":
columnDefinition.IsNullable = true;
Console.WriteLine(attributeInfoStr);
break;
case "DescriptionAttribute":
columnDefinition.Description = attr.Description; //字段说明
attributeInfoStr += string.Format("(说明:{0})", columnDefinition.Description);
Console.WriteLine(attributeInfoStr);
break;
default:
break;
}
} if (!string.IsNullOrWhiteSpace(columnDefinition.ColumnName) && !string.IsNullOrWhiteSpace(columnDefinition.DbType))
{
columnDefinitionList.Add(columnDefinition);
} Console.WriteLine();
} return columnDefinitionList;
} #region DBHelper /// <summary>
/// check数据库是否已存在,不存在则自动创建
/// </summary>
/// <param name="connectionString"></param>
/// <param name="schemaName"></param>
static void CheckSchema(string connectionString, string schemaName)
{
var pattern = @"Initial\s*Catalog\s*=\s*master";
Match match = Regex.Match(connectionString, pattern, RegexOptions.IgnoreCase);
if (match.Groups.Count == )
{
throw new ArgumentException();
}
var sql = string.Format(@"
if not exists(select 1 from sysdatabases where name='{0}')
create database {0}
", schemaName);
ExcuteSql(connectionString, sql);
} static bool ExcuteSql(string connectionString, string sql)
{
try
{
using (var conn = new SqlConnection(connectionString))
{
conn.Execute(sql);
}
return true;
}
catch (Exception ex)
{
return false;
}
} /// <summary>
/// 对字符串进行sql格式化,并且符合like查询的格式。
/// </summary>
/// <param name="sqlstr"></param>
/// <returns></returns>
static string ToSqlLike(string sqlstr)
{
if (string.IsNullOrEmpty(sqlstr)) return string.Empty;
StringBuilder str = new StringBuilder(sqlstr);
str.Replace("'", "''");
str.Replace("[", "[[]");
str.Replace("%", "[%]");
str.Replace("_", "[_]");
return str.ToString();
} #endregion } /// <summary>
/// 数据库 列定义
/// </summary>
public class ColumnDefinition
{
public string ColumnName { get; set; }
public bool IsPrimaryKey { get; set; }
/// <summary>
/// 标示种子
/// </summary>
public int Seed { get; set; }
/// <summary>
/// 标示增量
/// </summary>
public int Incr { get; set; }
public string DbType { get; set; }
public int MaxLength { get; set; }
/// <summary>
/// true 可为空, 否则 false 不可为空
/// </summary>
public bool IsNullable { get; set; }
public string Description { get; set; }
} #region Custom Attributes [AttributeUsage(AttributeTargets.Class)]
/// <summary>
/// 数据库 表名
/// </summary>
public class DBTableNameAttribute : Attribute
{
public string Name { get; set; }
} [AttributeUsage(AttributeTargets.Class)]
/// <summary>
/// 表的TEXTIMAGE ON特性
/// </summary>
public class TextImageOnAttribute : Attribute
{ } [AttributeUsage(AttributeTargets.Property)]
/// <summary>
/// 主键
/// </summary>
public class PrimaryKeyAttribute : Attribute
{
/// <summary>
/// 标示种子
/// </summary>
public int Seed { get; set; }
/// <summary>
/// 标示增量
/// </summary>
public int Incr { get; set; }
} [AttributeUsage(AttributeTargets.Property)]
/// <summary>
/// 数据类型
/// </summary>
public class DataTypeAttribute : Attribute
{
public string DbType { get; set; }
public int MaxLength { get; set; }
} [AttributeUsage(AttributeTargets.Property)]
/// <summary>
/// 允许Null值
/// </summary>
public class IsNullableAttribute : Attribute
{ } #endregion #region Table Model [TextImageOn]
/// <summary>
///
/// </summary>
public class TB_Enterprise
{
[PrimaryKey(Seed = , Incr = )]
[DataType(DbType = "int")]
public int EnterpriseId { get; set; } [DataType(DbType = "int")]
public int Status { get; set; } [DataType(DbType = "int")]
[IsNullable]
public int? IsFamous { get; set; } [DataType(DbType = "int")]
[IsNullable]
public int? CustomerLevel { get; set; } [IsNullable]
[DataType(DbType = "nvarchar", MaxLength = )]
[Description("企业名称")]
/// <summary>
/// 企业名称
/// </summary>
public string Name { get; set; } [IsNullable]
[DataType(DbType = "nvarchar", MaxLength = )]
public string Industry { get; set; } [DataType(DbType = "int")]
[IsNullable]
public int? Mode { get; set; } [DataType(DbType = "int")]
[IsNullable]
public int? Scale { get; set; } [DataType(DbType = "nvarchar", MaxLength = )]
[IsNullable]
public string City { get; set; } [DataType(DbType = "nvarchar", MaxLength = )]
[IsNullable]
public string WebSite { get; set; } [DataType(DbType = "ntext")]
[IsNullable]
public string DescText { get; set; } [DataType(DbType = "datetime")]
public DateTime CreateDate { get; set; } [DataType(DbType = "datetime")]
public DateTime ModifyDate { get; set; } [DataType(DbType = "datetime")]
[IsNullable]
public DateTime? ApproveDate { get; set; } [DataType(DbType = "nvarchar", MaxLength = )]
[IsNullable]
public string SourceName { get; set; } [DataType(DbType = "nvarchar", MaxLength = )]
[IsNullable]
public string License { get; set; } [DataType(DbType = "varchar", MaxLength = )]
[IsNullable]
public string CreateUser { get; set; } [DataType(DbType = "varchar", MaxLength = )]
[IsNullable]
public string ModifyUser { get; set; } [DataType(DbType = "int")]
[IsNullable]
public int? ProcessStatus { get; set; } [DataType(DbType = "varchar", MaxLength = )]
[IsNullable]
public string Abbr { get; set; } [DataType(DbType = "varchar", MaxLength = )]
[IsNullable]
public string NameInitial { get; set; } [DataType(DbType = "float")]
[IsNullable]
public decimal? Activity { get; set; } [DataType(DbType = "nvarchar", MaxLength = )]
[IsNullable]
public string Tags { get; set; } [DataType(DbType = "nvarchar", MaxLength = )]
[IsNullable]
public string ConsultantName { get; set; } [DataType(DbType = "nvarchar", MaxLength = )]
[IsNullable]
public string ConsultantComment { get; set; } [DataType(DbType = "int")]
[IsNullable]
public int? ConsultantId { get; set; } [DataType(DbType = "int")]
[IsNullable]
public int? DecoratePercent { get; set; } [DataType(DbType = "nvarchar", MaxLength = )]
[IsNullable]
public string ShortDesc { get; set; } [DataType(DbType = "int")]
[IsNullable]
public int? CertificationStatus { get; set; } [DataType(DbType = "bit")]
[IsNullable]
public bool? IsBDRecommended { get; set; } [DataType(DbType = "int")]
[IsNullable]
public int? ApproveStatus { get; set; } [DataType(DbType = "varchar", MaxLength = )]
[IsNullable]
public string ApproveResult { get; set; } [DataType(DbType = "int")]
[IsNullable]
public int? ApproveByUserId { get; set; }
} #endregion }

CodeFirst(反射+特性)的更多相关文章

  1. FreeSql (三十五)CodeFirst 自定义特性

    比如项目内已经使用了其它 orm,如 efcore,这样意味着实体中可能存在 [Key],但它与 FreeSql [Column(IsPrimary = true] 不同. Q: FreeSql 实体 ...

  2. C#利用反射+特性实现简单的实体映射数据库操作类

    附上源代码: using System; using System.Collections.Generic; using System.Data; using System.Linq; using S ...

  3. C#图解教程 第二十四章 反射和特性

    反射和特性 元数据和反射Type 类获取Type对象什么是特性应用特性预定义的保留的特性 Obsolete(废弃)特性Conditional特性调用者信息特性DebuggerStepThrough 特 ...

  4. C# 利用反射

    .NET基础篇——反射的奥妙 C#获取实体类属性名和值 | 遍历类对象 c#通过反射获取类上的自定义特性 C#利用反射+特性实现简单的实体映射数据库操作类

  5. C#语法——反射,架构师的入门基础。

    前言 编程其实就是写代码,而写代码目的就是实现业务,所以,语法和框架也是为了实现业务而存在的.因此,不管多么高大上的目标,实质上都是业务. 所以,我认为不要把写代码上升到科学的高度.上升到艺术就可以了 ...

  6. FreeSql (三)实体特性

    主键(Primary Key) class Topic { [Column(IsPrimary = true)] public int Id { get; set; } } 约定: 当没有指明主键时, ...

  7. FreeSql (四)实体特性 Fluent Api

    FreeSql 提供使用 Fluent Api, 在外部配置实体的数据库特性,Fluent Api 的方法命名与特性名保持一致,如下: fsql.CodeFirst .ConfigEntity< ...

  8. FreeSql (三十三)CodeFirst 类型映射

    前面有介绍过几篇 CodeFirst 内容文章,有 <(二)自动迁移实体>(https://www.cnblogs.com/FreeSql/p/11531301.html) <(三) ...

  9. FreeSql (三十四)CodeFirst 迁移说明

    FreeSql 支持 CodeFirst 迁移结构至数据库,这应该是(O/RM)必须标配的一个功能. 与其他(O/RM)不同FreeSql支持更多的数据库特性,而不只是支持基础的数据类型,这既是优点也 ...

随机推荐

  1. JSON 总结

          <!--Json格式配置映射 直接能访问JSON文本数据--> <system.webServer> <staticContent> <mimeM ...

  2. CMDB

    一.CMDB CMDB --Configuration Management Database 配置管理数据库, CMDB存储与管理企业IT架构中设备的各种配置信息,它与所有服务支持和服务交付流程都紧 ...

  3. 小波分解和合成的simulink仿真

    采用5-3提升小波的方法 小波分解 数据拆分 预测 更新 数据输出使能电路 电路共有两个输入三个输出,in1是数据输入,in2是输入数据有效信号,out1是更新后的低频信号,out2是预测的高频信号, ...

  4. phoenix elixir 框架简单试用

    备注:   官方提供的脚手架工具,我们可以直接使用,生成代码,同时需要nodejs 环境配置(比较简单,参考 相关资料即可)  1. 安装脚手架 mix archive.install https:/ ...

  5. sysbench fileio 压力测试

    备注:   使用的是yum 安装   1. 安装 yum install -y sysbench 2. 命令 fileio options: --file-num=N number of files ...

  6. Spring注入方式及用到的注解

    注入方式: 把DAO实现类注入到service实现类中,把service的接口(注意不要是service的实现类)注入到action中,注 入时不要new 这个注入的类,因为spring会自动注入,如 ...

  7. angular的指令独立作用域(以及$watch的使用)

    在编写指令的时候,会有一个独立作用域的问题(scope),他默认的是 scope:false 不创建自己的作用域,直接使用的就是父级的作用域, 问题:容易出现全局的污染,是的指令的重复性使用回出现一些 ...

  8. mysql存储引擎之myisam学习

    myisam存储引擎特点:1.不支持事务2.表级锁定(更新时锁整个表,其索引机制是表级索引,这虽然可以让锁定的实现成本很小,但是也同时大大降低 了其并发性能) 3.读写互相阻塞:不仅会在写入的时候阻塞 ...

  9. Python学习总结之一 -- 基础篇

    Python学习第一篇 一:写在前面 啊,最近我的新博客一直都没有更新学习内容了,只是最近一直都在忙着寻找实习机会(或许这只是一个借口,真实原因是我太懒惰了,改改改!).终于今天又投递了几个新的实习职 ...

  10. Unit03: 容器对路径的处理 、 Servlet特性

    Unit03: 容器对路径的处理 . Servlet特性 案例一:查询,增加员工: 重定向 处理请求资源路径 目录结构: 案例代码: package dao; import java.io.Seria ...