CodeFirst

简单的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;

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 > 0)
            {
                //可能需要创建数据库
                CheckSchema(ConnectionString, SchemaName);
                ConnectionString = ConnectionString.Replace(match.Groups[0].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 = 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 > 0 ? ",MaxLength:" + columnDefinition.MaxLength : "");

                            Console.WriteLine(attributeInfoStr);
                            break;
                        case "IsNullableAttribute":
                            columnDefinition.IsNullable = true;

                            Console.WriteLine(attributeInfoStr);
                            break;
                        default:
                            break;
                    }
                }

                if (!string.IsNullOrWhiteSpace(columnDefinition.ColumnName) && !string.IsNullOrWhiteSpace(columnDefinition.DbType))
                {
                    columnDefinitionList.Add(columnDefinition);
                }

                Console.WriteLine();
            }

            //数据库 表名
            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 > 0)
            {
                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 > 0 ? "(" + p.MaxLength + ")" : "", p.IsPrimaryKey && primaryKeyArr.Length <= 1 ? "IDENTITY(" + p.Seed + "," + p.Incr + ")" : "", p.IsNullable ? "NULL" : "NOT NULL");
                });

                if (primaryKeyArr != null && primaryKeyArr.Length > 0)
                {
                    //主键列
                    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]" : "");

                return sb.ToString();

            }

            return string.Empty;
        }

        #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 == 0)
            {
                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;
            }
        }

        #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; }
    }

    #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 = 1, Incr = 1)]
        [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 = 256)]
        /// <summary>
        /// 企业名称
        /// </summary>
        public string Name { get; set; }

        [IsNullable]
        [DataType(DbType = "nvarchar", MaxLength = 300)]
        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 = 256)]
        [IsNullable]
        public string City { get; set; }

        [DataType(DbType = "nvarchar", MaxLength = 512)]
        [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 = 50)]
        [IsNullable]
        public string SourceName { get; set; }

        [DataType(DbType = "nvarchar", MaxLength = 256)]
        [IsNullable]
        public string License { get; set; }

        [DataType(DbType = "varchar", MaxLength = 20)]
        [IsNullable]
        public string CreateUser { get; set; }

        [DataType(DbType = "varchar", MaxLength = 20)]
        [IsNullable]
        public string ModifyUser { get; set; }

        [DataType(DbType = "int")]
        [IsNullable]
        public int? ProcessStatus { get; set; }

        [DataType(DbType = "varchar", MaxLength = 50)]
        [IsNullable]
        public string Abbr { get; set; }

        [DataType(DbType = "varchar", MaxLength = 1)]
        [IsNullable]
        public string NameInitial { get; set; }

        [DataType(DbType = "float")]
        [IsNullable]
        public decimal? Activity { get; set; }

        [DataType(DbType = "nvarchar", MaxLength = 200)]
        [IsNullable]
        public string Tags { get; set; }

        [DataType(DbType = "nvarchar", MaxLength = 50)]
        [IsNullable]
        public string ConsultantName { get; set; }

        [DataType(DbType = "nvarchar", MaxLength = 500)]
        [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 = 100)]
        [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 = 500)]
        [IsNullable]
        public string ApproveResult { get; set; }

        [DataType(DbType = "int")]
        [IsNullable]
        public int? ApproveByUserId { get; set; }
    }

    #endregion

}
时间: 2024-10-12 06:26:36

CodeFirst的相关文章

Code-First简介

DocumentForEFCodeFirst *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !important; } /* BLOCKS =============================================================================*/ p, blockquote, ul, ol, dl, table, pre { ma

EF Core1.0 CodeFirst为Modell设置默认值!

当我们使用CodeFirst时,有时候需要设置默认值! 如下 public int Delete { get; set; } = 0; public string AdminName {get; set;} = "admin"; public bool CacheDbResults { get; set; } = true;

EntityTypeConfiguration Class in Code-First【Code First系列】

在我们学习Fluent API之前,先来看看Fluent API中重要的类--EntityTypeConfiguration吧. EntityTypeConfiguration类是Fluent API 中重要的类,这个类提供了重要的属性和方法来配置领域类,让我们可以不用按照约定的Code-First那样的配置来,配置我们的领域类. EntityTypeConfiguration类型可以通过调用DbModelBuilder类中的Entity<TEntity>()泛型方法得到. EntityTyp

EF Code-First 学习之旅 Code First Conventions

协定是一系列的默认规则用来自动配置领域中的概念模型 1:类型发现 Code-First对包含DBSet属性的类型创建表(包括这些类型的所有引用类型) public class Student { public Student() { } public int StudentID { get; set; } public string StudentName { get; set; } public DateTime DateOfBirth { get; set; } public byte[]

EF6(CodeFirst)+Mysql开发脱坑指南

废话 话说当年,在一个春光明媚的晌午,邂逅了迷人的丁香姑娘,从此拜倒在了她的石榴裙下,至今不能自拔,这位丁香姑娘就是ORM思想. 所谓ORM思想,我的理解就是根据一定的规则,把程序中的对象和数据库中的关系数据相互映射转换.在当年之前,我用ADO.NET编写数据持久层,拼接T-Sql语句,这是一个相当繁琐的过程,而且针对不同的数据库,还要调整T-Sql语句.记得,第一个网站上线的时候,数据库改成了MySql的,为了适配MySql,我改了两天的Sql语句.现在每每想起,都不禁摇头哂笑. ORM思想如

EF Codefirst(二)数据注释

CodeFirst通过分析我们在代码里编写的类,以及类之间的关系生成数据库表,以及表之间的各种关系.数据库的表会涉及到主键,外键,列是否为空,列类型等等. 我们要通过怎样的方式来暴露这些信息呢? CodeFirst通过DataAnnotations(在 System.ComponentModel.DataAnnotations 命名空间中 )特性类标示这些信息. 常用的一些标识如下 主键 如果不存在符合EF默认规则的主键时,用key标注也可.个人不赞成这样,遵守默认规则就好,免去不必要麻烦. p

Fluent API in Code-First【Code-First系列】

在前面的章节中,我们已经看到了各种不同的数据注解特性.现在我们来学习一下Fluent API. Fluent API是另外一种配置领域类的方式,它提供了更多的配置相比数据注解特性. Mappings[映射] To Database[转成数据库] Model-wide Mapping[模型映射] Set default Schema[设置默认的Schema] Set Custom Convetions[自定义约定] Entity Mapping[实体映射] To Single or Multipl

关于CodeFirst异常:无法确定类型&#39;XXX&#39;和类型‘YYY’之间的关联的主体端,必须使用关系 Fluent API 或数据注释显式配置此关联的主体端。

此错误的原因是,你配置两个实体间的关系为一对一 然而我认为的一对一关系是,两者之间必须存在一个主体, 也就是说,你不能表1的外键是表2的主键并且表1的主键是表2的外键, 这样不符合数据库式吧? 我想多数人犯这个错误是无意的,并不是想表1的外键是表2的主键并且表1的主键是表2的外键, 怎么改呢?确定主体! 主体就是你要把其他实体的主键存进来的实体. 把非实体的导航属性删除就ok了. 关于CodeFirst异常:无法确定类型'XXX'和类型'YYY'之间的关联的主体端,必须使用关系 Fluent A

EF学习总结——CodeFirst

EF面向数据的一软件应用程序的技术,从名称来看,Entity Framework,实体框架,为什么说是面向数据呢?这里涉及到了EF的操作原理.它可以直接通过建立的实体来映射到数据库中的每张表,同时通过数据库中的表来映射实体中的各个属性.那么这里就涉及到三个对象,数据库,实体和code,所以,EF在构建映射关系时,也包含三种不同的构建方式,DataBaseFirst,ModelFirst和CodeFirst. 关于前两种的构建方式,均属于图形化界面方式,根据提示一步一步往下走,很容易完成,第三种c

将EF项目从dbfirst转化为codefirst

一个脚本服务的项目,之前是先设计的数据库表,采用EF的dbfirst做的映射.项目完成后,出现迁移瓶颈. 1.dbfirst项目,如果数据库表结构做了调整,需要重新映射 2.当出现表结构一致,但数据库用户及密码发生变化时,原dbfirst映射无法适应新数据库,需要重新建立dbfirst映射.不易于迁移 考虑这个脚本服务的目地是: 1.采用EF6 codefirst(废弃dbfirst)2.目前脚本服务器以承载库是oracle,解决了oracle版本不一致造成兼容性问题3.可以直接将发布版的脚本服