EF6+MYSQL之初体验

初次使用EF6+MYSQL

这次的项目时间可拉得够长的,定制开发就是这样。客户真正用上了才能基本上不再改了。起先项目是php实现的,改造成桌面程序。用.net winform开发,像这种小项目肯定要用EF了。 以前一直用4.0,用DB First,把向导生成的模型扩展一下,另写一个分部类来实现bulkcopy等这种特殊需求。一直都是这样简单的用着,懒得花时间成本去搞高深的AOP/IOC/泛型工厂... 有时候就是越简单越好,当只会捉老鼠的猫就好。 这次依然还是使用的DB First。

经验总结:

1、EF6之CRUD

EF向导自动转换成的DbContext类:

public partial class POS_Entities : DbContext
    {
        public POS_Entities()
            : base("name=POS_Entities")
        {
        }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            throw new UnintentionalCodeFirstException();
        }

        public virtual DbSet<bm_brandclasses> bm_brandclasses { get; set; }
        public virtual DbSet<bm_brandsubclasses> bm_brandsubclasses { get; set; }
        public virtual DbSet<bm_membermng> bm_membermng { get; set; }
        public virtual DbSet<bm_memcard_privilege> bm_memcard_privilege { get; set; }
        public virtual DbSet<bm_memcardclasses> bm_memcardclasses { get; set; }
        public virtual DbSet<bm_pointmng> bm_pointmng { get; set; }
        public virtual DbSet<ls_busimng> ls_busimng { get; set; }
        public virtual DbSet<ls_cashierlist> ls_cashierlist { get; set; }
        public virtual DbSet<ls_cashierlist_detail> ls_cashierlist_detail { get; set; }
        public virtual DbSet<ls_cashiernum> ls_cashiernum { get; set; }
        public virtual DbSet<ls_commoditymng> ls_commoditymng { get; set; }
        public virtual DbSet<ls_couponmng> ls_couponmng { get; set; }
        public virtual DbSet<ls_couponmng_list> ls_couponmng_list { get; set; }
        public virtual DbSet<ls_handovermng> ls_handovermng { get; set; }
        public virtual DbSet<ls_promotionclasses> ls_promotionclasses { get; set; }
        public virtual DbSet<ls_promotionmng> ls_promotionmng { get; set; }
        public virtual DbSet<ls_promotionmng_subact> ls_promotionmng_subact { get; set; }
        public virtual DbSet<ls_promotionsubclasses> ls_promotionsubclasses { get; set; }
        public virtual DbSet<sa_manager> sa_manager { get; set; }
        public virtual DbSet<sa_num_auto> sa_num_auto { get; set; }
        public virtual DbSet<sa_role> sa_role { get; set; }
        public virtual DbSet<ls_leasemng> ls_leasemng { get; set; }
    }

我的扩展类:

public partial class POS_Entities
    {
        private static readonly BindingFlags bf = BindingFlags.Instance | BindingFlags.Public | BindingFlags.Static | BindingFlags.NonPublic;

        private static readonly Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
        public string ConnectionString
        {
            get
            {
                var ecb = new EntityConnectionStringBuilder(config.ConnectionStrings.ConnectionStrings["POS_Entities"].ConnectionString);
                return ecb.ProviderConnectionString;
            }
        }
        /// <summary>
        /// 执行Sql语句
        /// </summary>
        /// <param name="sql"></param>
        /// <returns></returns>
        public int ExecuteSql(string sql)
        {
            return this.Database.ExecuteSqlCommand(sql, new object[] { });
        }

        /// <summary>
        /// 返回查询的第一行第一列的值
        /// </summary>
        /// <param name="sqlText"></param>
        /// <returns></returns>
        public object ExecuteScalar(string sqlText)
        {
            var db = this.Database.Connection;
            try
            {
                if (db.State != ConnectionState.Open)
                    db.Open();
                var cmd = db.CreateCommand();
                cmd.CommandText = sqlText;
                return cmd.ExecuteScalar();
            }
            finally
            {
                db.Close();
            }
        }

        /// <summary>
        /// 使用同一个事物批量提交SQL
        /// </summary>
        /// <param name="sqls"></param>
        public bool BatchExecuteSqlWithTrans(List<string> sqls)
        {
            var dbConn = this.Database.Connection;
            if (dbConn.State != ConnectionState.Open)
                dbConn.Open();
            var cmd = dbConn.CreateCommand();
            var st = dbConn.BeginTransaction();
            try
            {
                HashSet<string> list = new HashSet<string>();
                cmd.Transaction = st;
                sqls.ForEach(delegate (string sqlTxt)
                {
                    cmd.CommandText = sqlTxt;
                    cmd.ExecuteNonQuery();
                });
                st.Commit();
                return true;
            }
            catch (Exception ex)
            {
                st.Rollback();
                return false;
                throw new Exception(ex.Message);
            }
            finally
            {
                dbConn.Close();
            }
        }

        #region MySql 批量插入
        /// <summary>
        /// 批量插入
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="tbName">要插入的目标表名称</param>
        /// <param name="columeArr">要插入的列名数组</param>
        /// <param name="listModels">要插入的实体数组</param>
        /// <param name="strConnection">数据库连接字符串</param>
        /// <returns></returns>
        public int BatchInsert<T>(string tbName, string[] columeArr, IList<T> listModels) where T : class, new()
        {
            if (listModels == null || listModels.Count == 0)
            {
                throw new ArgumentException("没有需要批量插入的数据");
            }
            int columes = columeArr.Length;
            StringBuilder sb = new StringBuilder();
            sb.AppendFormat("INSERT INTO {0} ", tbName);
            AppendColumes(sb, columeArr);
            sb.Append(" VALUES ");
            var listParamKeys = new List<string>();//参数的键值
            string paramKey = string.Empty;
            for (int i = 0; i < listModels.Count; i++)  //构造参数
            {
                sb.Append("(");
                for (int j = 0; j < columes; j++)
                {
                    paramKey = string.Format("@v_{0}_{1}", columeArr[j], columes * i + j); //参数前必须加入@
                    sb.Append(paramKey);
                    listParamKeys.Add(paramKey);
                    if (j < columes - 1)
                    {
                        sb.Append(",");
                    }
                }
                sb.Append("),");
            }
            var listParamValues = new List<object>();
            for (int i = 0; i < listModels.Count; i++)  //构造参数值数组
            {
                FastPrepareParamValue<T>(listModels[i], columeArr, listParamValues);
            }
            string sqlText = sb.ToString().Trim(‘,‘) + ";";
            int affectNum = ExecuteNonQuery(ConnectionString, CommandType.Text, sqlText, PrepareParameters(listParamKeys.ToArray(), listParamValues.ToArray()));
            return affectNum;
        }
        private int ExecuteNonQuery(string connectionString, CommandType cmdType, string cmdText, params MySqlParameter[] commandParameters)
        {
            MySqlCommand cmd = new MySqlCommand();
            using (MySqlConnection conn = new MySqlConnection(connectionString))
            {
                PrepareCommand(conn, null, cmd, cmdType, cmdText, commandParameters);
                int val = cmd.ExecuteNonQuery();
                cmd.Parameters.Clear();
                return val;
            }
        }
        private MySqlParameter[] PrepareParameters(string[] paramKeys, object[] paramValues)
        {
            MySqlParameter[] clonedParms = new MySqlParameter[paramKeys.Length];
            for (int i = 0; i < paramKeys.Length; i++)
            {
                clonedParms[i] = new MySqlParameter(paramKeys[i], paramValues[i]);
            }
            return clonedParms;
        }
        private void PrepareCommand(MySqlConnection conn, MySqlTransaction trans, MySqlCommand cmd, CommandType cmdType, string cmdText, MySqlParameter[] cmdParms)
        {
            if (conn.State != ConnectionState.Open)
                conn.Open();
            cmd.Connection = conn;
            cmd.CommandText = cmdText;
            if (trans != null)
                cmd.Transaction = trans;
            cmd.CommandType = cmdType;
            if (cmdParms != null)
            {
                foreach (MySqlParameter parm in cmdParms)
                    cmd.Parameters.Add(parm);
            }
        }

        private void AppendColumes(StringBuilder sb, string[] columeArr)
        {
            if (columeArr == null || columeArr.Length == 0)
            {
                throw new ArgumentException("插入列不能为空");
            }
            sb.Append("(");
            for (int i = 0; i < columeArr.Length; i++)
            {
                sb.Append(columeArr[i]);
                if (i < columeArr.Length - 1)
                {
                    sb.Append(",");
                }
            }
            sb.Append(")");
        }

        private void FastPrepareParamValue<T>(T model, string[] columeArr, List<object> listPramValues)
        {
            object objValue = null;
            var objType = model.GetType();
            var properties = objType.GetProperties(bf);
            foreach (var columeName in columeArr)
            {
                foreach (var propInfo in properties)
                {
                    if (string.Compare(columeName, propInfo.Name, true) != 0)
                    {
                        continue;
                    }
                    try
                    {
                        objValue = propInfo.GetValue(model);
                    }
                    catch
                    {
                        objValue = null;
                    }
                    finally
                    {
                        listPramValues.Add(objValue);
                    }
                    break;
                }
            }
        }
        #endregion

        public DataSet Query(CommandType cmdType, string cmdText, params MySqlParameter[] commandParameters)
        {
            MySqlCommand cmd = new MySqlCommand();
            MySqlConnection conn = new MySqlConnection(ConnectionString);
            try
            {
                PrepareCommand(conn, null, cmd, cmdType, cmdText, commandParameters);
                MySqlDataAdapter adapter = new MySqlDataAdapter();
                adapter.SelectCommand = cmd;
                DataSet ds = new DataSet();
                adapter.Fill(ds);
                cmd.Parameters.Clear();
                conn.Close();
                return ds;
            }
            catch (Exception e)
            {
                throw e;
            }
        }
    }

扩展类的目的是使用熟悉的原生ado.net的方式来避免趟EF的坑(未必有的)。 

1)增

db.cashierlist.Add(bill);
                    try
                    {
                        db.Entry<cashierlist>(bill).State = System.Data.Entity.EntityState.Added;
                        db.SaveChanges();
                        result.Success = true;
                        result.Message = "操作成功!";
                        result.Result = bill;
                    }
                    catch (Exception ex)
                    {
                        var exx = ex.InnerException == null ? ex : ex.InnerException;
                        result.Message = exx.Message;
                    }

这里好像就是需要写"db.Entry<T>(bill).State = System.Data.Entity.EntityState.Added",显式的标记为"System.Data.Entity.EntityState.Added",即新增状态。

2)改和删好像跟以前一样的没啥说的。

3)查

var dbExists = db.ls_cashierlist.SqlQuery("select * from ls_cashierlist where cl_sn=‘" + bill.cl_sn + "‘").FirstOrDefaultAsync().Result;

toListAsync()/FirstOrDefaultAsync()/SingleAsync()等陌生方法给我带来了困惑。以前同步方式调用这些api习惯了,现在统统变成了支持异步的方法了。不深究,改成同步的方式就是取XXX方法的().Result就行了。

2、关于.net连接mysql

1)MYSQL某些字段日期时间类型如果是允许空值时且存了空值那么,MYSQL默认写的是“0000-00-00 00:00:00”这样子,这个其实在连接字符串里面有几个选项可以参考一下,就是"allowzerodatetime"和"convertzerodatetime".

2)中文乱码,需要指定字符集,比如:characterset=utf8

3、Http get或者post请求超时时间控制

由于winform客户端在发起Http get或者post请求时刚开始设置的超时时间是5秒,后来发现请求在服务器端的webapi中处理时间比较久时,客户端就直接什么都不返回,自动被终止了,两边都没有异常。自动被超时时间这个参数处理掉了。

还以为是那些个异步方法的使用有问题就是说webapi在返回值的时候没有等到异步方法返回就开始返回给客户端了。这是错误的,前面已经把异步改成同步了。

后来增加超时时间就能正常返回了。记录一下,我自己能看懂就好

还是老规矩,晒上几张图作为结束:

时间: 2024-11-06 06:46:41

EF6+MYSQL之初体验的相关文章

MySQL数据库初体验(含MySQL数据库5.7.17手工编译安装)

MySQL数据库初体验 Ram:随机性访问存储器,断电丢失数据 内存Rom:只读访问存储器,不会丢失数据 管理存储的数据,数据的增删改查,数据的迁移,保证数据的私密性 1.数据库的基本概念2.数据库的发展3.主流的数据库介绍4.编译安装mysql5.操作mysql 数据库的基本概念 数据: 1.描述事物的符号记录称为数据(Data)2.包括数字,文字.图形.图像.声音.档案记录等3.以"记录"形式按统一-的格式进行存储 表: 1.将不同的记录组织在一-起,就形成了"表&quo

(三)IdentityServer4 结合 Mysql 之初体验

前面写的示例中,IdeneityServer使用的是内存缓存的存储方式,所有的配置都写在Config.cs里.在实际应用中,应该使用数据库存储方式,方便随时配置,如添加新的用户.资源.客户端,也可以节省服务器内存. 本文从三个方面来实现IdentityServer4结合Mysql实现数据库存储方式,分别是客户端及资源数据.令牌及授权码数据以及用户数据. 一.准备内容 mysql 数据库 Nuget 所需包 IdentityServer4.EntityFramework Pomelo.Entity

JMS服务器ActiveMQ的初体验并持久化消息到MySQL数据库中

JMS服务器ActiveMQ的初体验并持久化消息到MySQL数据库中 一.JMS的理解JMS(Java Message Service)是jcp组织02-03年定义了jsr914规范(http://jcp.org/en/jsr/detail?id=914),它定义了消息的格式和消息传递模式:消息包括:消息头,消息扩展属性和消息体,其结构看起来与SOAP非常的相似,但一般情况下,SOAP主要关注远程服务调用,而消息则专注于信息的交换:消息分为:消息生产者,消息服务器和消息消费者.生产者与消费者之间

hibernate--CRUD初体验

hibernate的crud操作初体验. 看具体实例 package com.fuwh.model; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import org.hibernate.annotations.GenericGenerator; @Entity publ

Question2Answer初体验

Question2Answer初体验 高质量的问答社区十分有价值,很多无法解决的问题能通过问答社区找到解决办法,而对于站长来说,垂直的问答社区也很有潜力.最近盯上问答这一块,发现和我的一些思路很符合,决定把手头的一个网站转成问答形式的社区. 最开始是想完全从头开始写一个,但个人精力有限,目前还有一些别的想法等待实施,只能尽量用更快的办法来搭建它.于是,在开源程序上做扩展就是最好的选择. 网上PHP的独立问答社区非常的少,找来找去,最后锁定question2answer(以下简称QA). QA是一

Node.js 网页瘸腿爬虫初体验

延续上一篇,想把自己博客的文档标题利用Node.js的request全提取出来,于是有了下面的初哥爬虫,水平有限,这只爬虫目前还有点瘸腿,请看官你指正了. // 内置http模块,提供了http服务器和客户端功能 var http=require("http"); // 内置文件处理模块 var fs=require('fs'); // 创建一个将流数据写入文件的WriteStream对象 var outstream=fs.createWriteStream('./1.txt'); /

Django初体验——搭建简易blog

前几天在网上看到了篇采用Django搭建简易博客的视频,好奇心驱使也就点进去学了下,毕竟自己对于Django是无比敬畏的,并不是很了解,来次初体验. 本文的操作环境:ubuntu.python2.7.Django1.8.6.Pycharm5.其实自从使用了ubuntu之后就很神奇的喜欢上了它,真的用起来方便很多. 1.Django项目文件并创建blog应用 (1)可以在终端中建立Django项目,使用django-admin startproject ...直接上图: 建立blog应用: (2)

Net Core平台灵活简单的日志记录框架NLog初体验

Net Core平台灵活简单的日志记录框架NLog初体验 前几天分享的"[Net Core集成Exceptionless分布式日志功能以及全局异常过滤][https://www.cnblogs.com/yilezhu/p/9339017.html]" 有人说比较重量,生产环境部署也比较麻烦.因此就有了今天的这篇文章.如果你的项目(网站或者中小型项目)不是很大,日志量也不多的话可以考虑NLog+Mysql的组合.因为NLog具有高性能,易于使用,易于扩展和灵活配置的特点能够让你快速集成日

19JDBC初体验

一.JDBC常用类和接口 JDBC(Java DataBase Connectivity,java数据库连接)是一种用于执行SQL语句的Java API.JDBC是Java访问数据库的标准规范,可以为不同的关系型数据库提供统一访问,它由一组用Java语言编写的接口和类组成. JDBC与数据库驱动的关系:接口与实现类的关系. 二.JDBC常用类和接口 JDBC有关的类:都在java.sql 和 javax.sql 包下. 接口在Java中是用来定义 `行为规范的`.   接口必须有实现类. JDB