CodeFirst(反射+特性)
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(反射+特性)的更多相关文章
- FreeSql (三十五)CodeFirst 自定义特性
比如项目内已经使用了其它 orm,如 efcore,这样意味着实体中可能存在 [Key],但它与 FreeSql [Column(IsPrimary = true] 不同. Q: FreeSql 实体 ...
- C#利用反射+特性实现简单的实体映射数据库操作类
附上源代码: using System; using System.Collections.Generic; using System.Data; using System.Linq; using S ...
- C#图解教程 第二十四章 反射和特性
反射和特性 元数据和反射Type 类获取Type对象什么是特性应用特性预定义的保留的特性 Obsolete(废弃)特性Conditional特性调用者信息特性DebuggerStepThrough 特 ...
- C# 利用反射
.NET基础篇——反射的奥妙 C#获取实体类属性名和值 | 遍历类对象 c#通过反射获取类上的自定义特性 C#利用反射+特性实现简单的实体映射数据库操作类
- C#语法——反射,架构师的入门基础。
前言 编程其实就是写代码,而写代码目的就是实现业务,所以,语法和框架也是为了实现业务而存在的.因此,不管多么高大上的目标,实质上都是业务. 所以,我认为不要把写代码上升到科学的高度.上升到艺术就可以了 ...
- FreeSql (三)实体特性
主键(Primary Key) class Topic { [Column(IsPrimary = true)] public int Id { get; set; } } 约定: 当没有指明主键时, ...
- FreeSql (四)实体特性 Fluent Api
FreeSql 提供使用 Fluent Api, 在外部配置实体的数据库特性,Fluent Api 的方法命名与特性名保持一致,如下: fsql.CodeFirst .ConfigEntity< ...
- FreeSql (三十三)CodeFirst 类型映射
前面有介绍过几篇 CodeFirst 内容文章,有 <(二)自动迁移实体>(https://www.cnblogs.com/FreeSql/p/11531301.html) <(三) ...
- FreeSql (三十四)CodeFirst 迁移说明
FreeSql 支持 CodeFirst 迁移结构至数据库,这应该是(O/RM)必须标配的一个功能. 与其他(O/RM)不同FreeSql支持更多的数据库特性,而不只是支持基础的数据类型,这既是优点也 ...
随机推荐
- Servlet实现文件上传和下载
对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,如果直接使用Servlet获取上传文件的输入流然后再解析里面的请求参数是比较麻烦,所以一般选择采用apache的开源工具commo ...
- TLS支持版本检测
今天有开发同事询问“生产环境的TLS版本是多少”,这个问题还真没太关注过,首先想到的是通过Chrome浏览器的开发者工具查看一下,访问https页面查看如下: 这太概是说使用了TLS1.2,于是截图给 ...
- 通过Java Api与HBase交互
HBase提供了Java Api的访问接口,掌握这个就跟Java应用使用RDBMS时需要JDBC一样重要,本文将继续前两篇文章中blog表的示例,介绍常用的Api. import java.io.IO ...
- P2P UPD打洞原理
转自:http://blog.pfan.cn/fengfei/18828.html 首先先介绍一些基本概念: NAT(Network Address Tr ...
- SharePoint2013 Online中InfoPath 无法调用WebService
传说微软office365中国区服务器已经迁移到国内,试了下速度果然比之前快了很多,不过随后测试了个简单的功能,还是直接被打击了. 准备在online版本中做一个简单的报销流程测试测试,于是先用Inf ...
- 最近项目和java对接,涉及到java的DESede加解密算法
google后找到这个作者的一篇博客,搬过来用 http://hersface.com/page/17.html <?php class DESede{ /** * 加密 * @param $d ...
- flask之bootstrap4
pip install bootstrap-flask from flask_bootstrap import Bootstrap from flask import Flask bootstra ...
- Jenkins的项目管理
新建Item 使用Jenkins最重要的是能够创建一些工作流,除了部署,还能做很多流程上的事情.同样,一条条项目建起来需要做一定的管理,在Jenkins首页Jenkins->新建可以按自己的需要 ...
- SpringMVC日志管理(自定义异常及自定义注解)
近期为了规范公司老旧项目的日志,主要也是为了便于日后错误排查以及加强对业务系统的监控,准备对原有的日志输出进行简单的改造. 解决思路 1.通过自定义异常来将可能出现的问题分为两大类,业务类及系统类.同 ...
- 项目中Map端数据处理不均匀性分析
Map任务的不均匀性 最近发现Map端数据越来越不均匀,而处理输入的数据,写到本地磁盘的数据量都差不多,我们随便拿出来两个attempt任务(当前map数量为64个),33和45,33的counter ...