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支持更多的数据库特性,而不只是支持基础的数据类型,这既是优点也 ...
 
随机推荐
- CF1117A Best Subsegment
			
CF1117A Best Subsegment 乍一看好像很难,仔细想一下发现就是弱智题... 任意一段平均数显然不会超过最大的数,若只取最大数即可达到平均数为最大数. 于是只用取最长的一段连续的最大 ...
 - hadoop入门手册1:hadoop【2.7.1】【多节点】集群配置【必知配置知识1】
			
问题导读 1.说说你对集群配置的认识?2.集群配置的配置项你了解多少?3.下面内容让你对集群的配置有了什么新的认识? 目的 目的1:这个文档描述了如何安装配置hadoop集群,从几个节点到上千节点.为 ...
 - 《DSP using MATLAB》示例Example 6.12
			
上代码: % x = -8:7 y = TwosComplement(x, 4) y = dec2bin(y, 4); disp(sprintf('%s', [y'; char(ones(1, 16) ...
 - qt ui程序使用Linux的文件操作open、close (转)
			
原文地址:qt ui程序使用Linux的文件操作open.close 作者:kjpioo 提出这个问题是因为在qt的QWidget类型的对象中,close()函数会和QWidget::close()冲 ...
 - Eclipse导入工程后,XDoclet错误:Missing library: xdoclet-1.2.1.jar. Select the home directory for XDoclet
			
这几天在使用Open Health Tools的OpenXDS工程,在导入Eclipse后,出现下面的错误: 遂google之,在网上找到了答案.答案网址为http://blog.v-s-f.co.u ...
 - 快速创建yii2 RESTful api的小记
			
1.复制backend的应用到同级目录,改名叫api 2.然后就是配置项修改,common和api目录下的 common下: bootstrap.php最后添加一行配置 api/config/main ...
 - 数组游标实现对数组的各种操作(PHP学习)
			
如何不用foreach实现对数组实现循环? 答:我们只需要模拟foreach就行了,数组在执行foreach循环的时候,是有一个游标指向当前数组循环到的值, 那如果我们能拿到这个游标,并且操作游标,使 ...
 - HTTP 报文首部
			
1.HTTP 报文首部 HTTP 协议的请求和响应报文中必定包含 HTTP 首部.首部内容为客户端和服务器分别处理请求和响应提供所需要的信息. 1)HTTP请求报文:在请求中,HTTP报文由方法.UR ...
 - java代码--------实现随机输出100个随机数,10行,0--到9的数字
			
总结:妹纸不是那么会表述,如有不妥之处,请提出来 package com.sads; //杰伦的世界 //实现在0-100个数中,随机输出数每行10个数,也就是10行10列,这些数在0---到9之间 ...
 - Java中的强制类型转换
			
例如,当程序中需要将 double 型变量的值赋给一个 int 型变量,该如何实现呢? 显然,这种转换是不会自动进行的!因为 int 型的存储范围比 double 型的小.此时就需要通过强制类型转换来 ...