CodeFirst

Posted The pre-dawn darkness will not

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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

}

 

以上是关于CodeFirst的主要内容,如果未能解决你的问题,请参考以下文章

EF CodeFirst 通过代码生成数据库

EF架构~codeFirst从初始化到数据库迁移

CodeFirst

EF架构~codeFirst从初始化到数据库迁移

我们是怎么实现Grpc CodeFirst

使用CodeFirst创建并更新数据库