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在返回值的时候没有等到异步方法返回就开始返回给客户端了。这是错误的,前面已经把异步改成同步了。
后来增加超时时间就能正常返回了。记录一下,我自己能看懂就好
还是老规矩,晒上几张图作为结束:



EF6+MYSQL之初体验的更多相关文章
- Net Core平台灵活简单的日志记录框架NLog+Mysql组合初体验
Net Core平台灵活简单的日志记录框架NLog初体验 前几天分享的"[Net Core集成Exceptionless分布式日志功能以及全局异常过滤][https://www.cnblog ...
- Mysql Workbench初体验
可以画图,建立表关系. 分类整理数据表. 可以直接导出sql语句. 可以导出png图片. 可以连接mysql数据库. 基本满足了各项需求. 这次初体验只是基本的功能,这个软件对于mysql还是很牛的.
- Web开发学习之路--Eclipse+Tomcat+mysql之初体验
学习了一段时间android,正好要用到android和服务器之间的交互,既然要学习android,那么就涉猎下服务器端的开发了,以前学过php,用thinkphp很快可以搭建起来,但是android ...
- mysql/mariadb 初体验
距离申请这个博客号已经过了九个月,思前想后还是把知识沉淀放这里吧,不过初心一样,依旧是 '谨以此文,见证成果'.有 兴趣的话也欢迎大家去我的csdn博客转一转.以下是正文: 1.mysql安装 win ...
- MySQL数据库初体验
一.数据库的基本概念1.数据(Data) 描述事物的符号记录 包括数字,文字,图形,图像,声音,档案记录等 以"记录"形式按统一的格式进行存储 2.表 将不同的记录组织在一起 用来 ...
- Net Core平台灵活简单的日志记录框架NLog+SqlServer初体验
Net Core平台灵活简单的日志记录框架NLog+SqlServer初体验 前几天分享的"[Net Core平台灵活简单的日志记录框架NLog+Mysql组合初体验][http://www ...
- JMS服务器ActiveMQ的初体验并持久化消息到MySQL数据库中
JMS服务器ActiveMQ的初体验并持久化消息到MySQL数据库中 一.JMS的理解JMS(Java Message Service)是jcp组织02-03年定义了jsr914规范(http://j ...
- 你不知道的MySQL,以及MariaDB初体验
MySQL 是一个跨世纪的伟大产品,它最早诞生于 1979 年,距今已经有 40 多年的历史了,而如今比较主流的 Java 语言也只是 1991 年才诞生的,也就是说 MySQL 要比 Java 的诞 ...
- Question2Answer初体验
Question2Answer初体验 高质量的问答社区十分有价值,很多无法解决的问题能通过问答社区找到解决办法,而对于站长来说,垂直的问答社区也很有潜力.最近盯上问答这一块,发现和我的一些思路很符 ...
随机推荐
- 说不尽的MVVM(5) - 消息满天飞
知识预备 阅读本文,我假定你具备以下知识: C#和WPF基础知识 Lambda表达式 清楚ViewModel的职责 如果我们的程序需要弹出一个MessageBox,我们应该怎么做? 我见过不少人在Vi ...
- Spring MVC + jpa框架搭建,及全面分析
一,hibernate与jpa的关系 首先明确一点jpa是什么?以前我就搞不清楚jpa和hibernate的关系. 1,JPA(Java Persistence API)是Sun官方提出的Java持久 ...
- paip.环境配置整合 ibatis mybatis proxool
paip.环境配置整合 ibatis mybatis proxool 索引: ///////////1.调用 ///////////////2. ibatis 主设置文件 com/mijie/ho ...
- 每天一个linux命令(5):rm 命令
昨天学习了创建文件和目录的命令mkdir ,今天学习一下linux中删除文件和目录的命令: rm命令.rm是常用的命令,该命令的功能为删除一个目录中的一个或多个文件或目录,它也可以将某个目录及其下的所 ...
- Adafruit的树莓派教程第五课:使用控制电缆
Adafruit的树莓派教程第五课:使用控制电缆 时间 2014-05-09 01:11:20 极客范 原文 http://www.geekfan.net/9095/ 主题 Raspberry PiM ...
- “代理XP”组件已作为此服务器安全配置的一部分被关闭的解决办法
代理XP”组件已作为此服务器安全配置的一部分被关闭.系统管理员可以使用sp_configure来启用“代理XP”.有关启用“代理XP”的详细信息,请参阅SQL Server联机丛书中的“外围应用配置器 ...
- mysql 优化配置参数详解
在 my.cnf 文件中 各设置参数的含义如下: innodb_data_home_dir 这是InnoDB表的目录共用设置.如果没有在 my.cnf 进行设置,InnoDB 将使用MySQL的 da ...
- [界面开发新秀]免费的AYUI,开发360领航版系列教程[2/40]
<界面开发风AYUI-基于WPF By AY> 大家好! 距离上篇博客发布有10天了,因为我在开发AYUI4.X效果更惊艳 我是AY,很高兴,终于可以写自己的作品的,网络博 ...
- HDU 4759 Poker Shuffle
Poker Shuffle Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Tot ...
- 无法import的原因(ImportError: No module named *****)
python中,每个py文件被称之为模块,每个具有__init__.py文件的目录被称为包.只要模块或者包所在的目录在sys.path中,就可以使用import 模块或import 包来使用. 如果想 ...