12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055 |
- using System;
- using System.Collections.Generic;
- using System.Data;
- using System.Data.Common;
- using System.Diagnostics;
- using System.Linq;
- using System.Reflection;
- using System.Text;
- namespace LJLib.DAL.SQL
- {
- /// <summary>
- /// 全局初始化时,需要添加要支持的引擎(SqlServer/Sqlite)
- /// </summary>
- internal static class DbSqlHelper
- {
- /// <summary>
- /// 从数据库获取当前时间
- /// SQL Server :SELECT GETDATE()
- /// SQLite :SELECT DATETIME()
- /// </summary>
- public static DateTime GetServerTime<TCommand>(TCommand cmd) where TCommand : DbCommand
- {
- var engine = GetEngine(cmd.GetType());
- return engine.GetServerTime(cmd);
- }
- /// <summary>
- /// 获取单表中符合条件的行数
- /// </summary>
- public static int SelectCount<TCommand>(TCommand cmd, string table, string wherestr, IDictionary<string, object> sqlparams = null) where TCommand : DbCommand
- {
- string strcmd = "SELECT COUNT(0) FROM " + table;
- if (!string.IsNullOrEmpty(wherestr))
- {
- wherestr = wherestr.Trim();
- strcmd += " WHERE " + wherestr;
- }
- cmd.CommandText = strcmd;
- cmd.CommandType = CommandType.Text;
- cmd.Parameters.Clear();
- if (sqlparams != null)
- {
- foreach (var sqlparam in sqlparams)
- {
- var value = sqlparam.Value;
- if (value == null)
- {
- value = DBNull.Value;
- }
- AddWithValue(cmd, sqlparam.Key, value);
- }
- }
- return Convert.ToInt32(cmd.ExecuteScalar());
- }
- /// <summary>
- /// 添加参数值
- /// </summary>
- private static void AddWithValue<TCommand>(TCommand cmd, string name, object value) where TCommand : DbCommand
- {
- var engine = GetEngine(cmd.GetType());
- engine.AddWithValue(cmd, name, value);
- if (cmd.Parameters[name].Value == null)
- {
- cmd.Parameters[name].Value = DBNull.Value;
- }
- }
- public static void SelectJoin<TCommand, T>(TCommand cmd, string selectStr, string whereStr, IDictionary<string, object> parms, string orderByStr, string outputFields, int pageindex, int pagesize, List<T> returnList)
- where TCommand : DbCommand
- where T : new()
- {
- cmd.CommandText = SqlStrHelper.BuildSelectStr(selectStr, ref outputFields, whereStr, orderByStr, pageindex, pagesize); ;
- cmd.CommandType = CommandType.Text;
- cmd.Parameters.Clear();
- if (parms != null)
- {
- foreach (var parm in parms)
- {
- AddWithValue(cmd, parm.Key, parm.Value);
- }
- }
- var properties = GetProperties(typeof(T), outputFields);
- GetValues(cmd, returnList, properties);
- }
- private static object ConvertValue(Type parmType, object value)
- {
- if (!parmType.IsAssignableFrom(value.GetType()))
- {
- if (parmType.IsAssignableFrom(typeof(byte)))
- {
- value = Convert.ToByte(value);
- }
- else if (parmType.IsAssignableFrom(typeof(sbyte)))
- {
- value = Convert.ToSByte(value);
- }
- else if (parmType.IsAssignableFrom(typeof(short)))
- {
- value = Convert.ToInt16(value);
- }
- else if (parmType.IsAssignableFrom(typeof(ushort)))
- {
- value = Convert.ToUInt16(value);
- }
- else if (parmType.IsAssignableFrom(typeof(int)))
- {
- value = Convert.ToInt32(value);
- }
- else if (parmType.IsAssignableFrom(typeof(uint)))
- {
- value = Convert.ToUInt32(value);
- }
- else if (parmType.IsAssignableFrom(typeof(long)))
- {
- value = Convert.ToInt64(value);
- }
- else if (parmType.IsAssignableFrom(typeof(ulong)))
- {
- value = Convert.ToUInt64(value);
- }
- else if (parmType.IsAssignableFrom(typeof(float)))
- {
- value = Convert.ToSingle(value);
- }
- else if (parmType.IsAssignableFrom(typeof(double)))
- {
- value = Convert.ToDouble(value);
- }
- else if (parmType.IsAssignableFrom(typeof(decimal)))
- {
- value = Convert.ToDecimal(value);
- }
- else if (parmType.IsAssignableFrom(typeof(bool)))
- {
- value = Convert.ToBoolean(value);
- }
- else if (parmType.IsAssignableFrom(typeof(bool)))
- {
- value = Convert.ToBoolean(value);
- }
- else if (parmType.IsAssignableFrom(typeof(char)))
- {
- value = Convert.ToChar(value);
- }
- else if (parmType.IsAssignableFrom(typeof(DateTime)))
- {
- value = Convert.ToDateTime(value);
- }
- else if (parmType.IsAssignableFrom(typeof(string)))
- {
- value = Convert.ToString(value);
- }
- else if (parmType.IsEnum)
- {
- value = Enum.ToObject(parmType, value);
- }
- else
- {
- throw new Exception(string.Format("不能将{0}转换成{1}", value.GetType(), parmType));
- }
- }
- return value;
- }
- public static int Select<TCommand, T>(TCommand cmd, string tablename, string whereStr, IDictionary<string, object> parms, string orderStr, int pagesize, int pageindex, IList<T> modles, IDictionary<string, string> maps, string fields)
- where TCommand : DbCommand
- where T : new()
- {
- var strCmd = string.Format("SELECT {0} FROM {1}", fields, tablename);
- cmd.CommandText = SqlStrHelper.BuildSelectStr(strCmd, ref fields, whereStr, orderStr, pageindex, pagesize);
- cmd.CommandType = CommandType.Text;
- cmd.Parameters.Clear();
- if (parms != null)
- {
- foreach (var parm in parms)
- {
- AddWithValue(cmd, parm.Key, parm.Value);
- }
- }
- var targetMaps = GetTargetMaps<T>(maps, fields);
- using (var reader = cmd.ExecuteReader())
- {
- while (reader.Read())
- {
- T modle = new T();
- GetValue(reader, modle, targetMaps);
- modles.Add(modle);
- }
- }
- return modles.Count;
- }
- private static void GetValue(DbDataReader reader, object modle, Dictionary<string, PropertyInfo> targetMaps)
- {
- foreach (var property in targetMaps)
- {
- MethodInfo setMethod = property.Value.GetSetMethod();
- if (setMethod == null)
- {
- continue;
- }
- object value = null;
- try
- {
- value = reader[property.Key];
- }
- catch (Exception)
- {
- continue;
- }
- if (value == null || value == DBNull.Value)
- {
- continue;
- }
- if (value is string)
- {
- value = value.ToString().Trim();
- }
- var parmType = setMethod.GetParameters()[0].ParameterType;
- value = ConvertValue(parmType, value);
- setMethod.Invoke(modle, new object[] { value });
- }
- }
- public static int Select<TCommand, T>(TCommand cmd, IList<T> modles, string wherestr, string fields = "*")
- where TCommand : DbCommand
- where T : new()
- {
- return Select(cmd, modles, wherestr, null, null, fields, 0, 0);
- }
- public static int Select<TCommand, T>(TCommand cmd, IList<T> modles, string wherestr, IDictionary<string, object> sqlparams, string fields = "*")
- where TCommand : DbCommand
- where T : new()
- {
- return Select(cmd, modles, wherestr, sqlparams, null, fields, 0, 0);
- }
- public static int Select<TCommand, T>(TCommand cmd, IList<T> modles, string wherestr, IDictionary<string, object> sqlparams, int pageindex, int pagesize, string orderstr, string fields = "*")
- where TCommand : DbCommand
- where T : new()
- {
- return Select(cmd, modles, wherestr, sqlparams, orderstr, fields, pageindex, pagesize);
- }
- public static int Select<TCommand, T>(TCommand cmd, IList<T> modles, string whereStr, IDictionary<string, object> sqlparams, string orderByStr, string outputFields, int pageindex, int pagesize)
- where TCommand : DbCommand
- where T : new()
- {
- if (modles.IsReadOnly)
- {
- throw new ArgumentException("参数modles不能为只读");
- }
- var propertyies = GetProperties(typeof(T), outputFields);
- if (propertyies.Count == 0)
- {
- propertyies = new List<PropertyInfo>(GetProperties(typeof(T)).Values);
- }
- var strCmd = string.Empty;
- foreach (var propertyInfo in propertyies)
- {
- if (string.IsNullOrEmpty(strCmd))
- {
- strCmd = propertyInfo.Name;
- }
- else
- {
- strCmd += "," + propertyInfo.Name;
- }
- }
- strCmd = "SELECT " + strCmd + " FROM " + typeof(T).Name;
- var outCmdStr = SqlStrHelper.BuildSelectStr(strCmd, ref outputFields, whereStr, orderByStr, pageindex, pagesize);
- cmd.CommandText = outCmdStr;
- cmd.CommandType = CommandType.Text;
- cmd.Parameters.Clear();
- if (sqlparams != null)
- {
- foreach (var parm in sqlparams)
- {
- AddWithValue(cmd, parm.Key, parm.Value);
- }
- }
- GetValues(cmd, modles, propertyies);
- return modles.Count;
- }
- private static void GetValues<TCommand, T>(TCommand cmd, IList<T> modles, IList<PropertyInfo> propertyies)
- where TCommand : DbCommand
- where T : new()
- {
- try
- {
- using (var reader = cmd.ExecuteReader())
- {
- while (reader.Read())
- {
- T modle = new T();
- GetValue(reader, modle, propertyies);
- modles.Add(modle);
- }
- }
- }
- catch (Exception)
- {
- //Debug.Write(cmd.CommandText);
- throw;
- }
- }
- private static void GetValue<T>(DbDataReader reader, T modle, IList<PropertyInfo> propertyies)
- {
- foreach (PropertyInfo property in propertyies)
- {
- MethodInfo setMethod = property.GetSetMethod();
- if (setMethod == null)
- {
- continue;
- }
- object value = null;
- try
- {
- value = reader[property.Name];
- }
- catch (Exception)
- {
- continue;
- }
- if (value == null || value == DBNull.Value)
- {
- continue;
- }
- if (value is string)
- {
- value = value.ToString().Trim();
- }
- var parmType = setMethod.GetParameters()[0].ParameterType;
- value = ConvertValue(parmType, value);
- setMethod.Invoke(modle, new object[] { value });
- }
- }
- private static object _pksyncRoot = new object();
- private static Dictionary<Type, string[]> _type_pks = new Dictionary<Type, string[]>();
- private static string[] GetPKs(Type type)
- {
- // DONE: 返回模型类的主键
- lock (_pksyncRoot)
- {
- if (_type_pks.ContainsKey(type))
- {
- return _type_pks[type];
- }
- var attrs = type.GetCustomAttributes(typeof(PK), true);
- if (attrs.Length == 0)
- {
- _type_pks[type] = new string[] { };
- }
- else
- {
- PK pk = attrs[0] as PK;
- _type_pks[type] = pk.keys;
- }
- return _type_pks[type];
- }
- }
- public static int SelectOne<TCommand, T>(TCommand cmd, string tablename, string whereStr, IDictionary<string, object> parms, T Modle, string fields) where TCommand : DbCommand
- {
- // 生成语句
- var propertyies = GetProperties(typeof(T), fields);
- if (propertyies.Count == 0)
- {
- propertyies = new List<PropertyInfo>(GetProperties(typeof(T)).Values);
- }
- var strCmd = string.Empty;
- foreach (var propertyInfo in propertyies)
- {
- if (string.IsNullOrEmpty(strCmd))
- {
- strCmd = propertyInfo.Name;
- }
- else
- {
- strCmd += "," + propertyInfo.Name;
- }
- }
- strCmd = "SELECT " + strCmd + " FROM " + tablename;
- if (!string.IsNullOrEmpty(whereStr))
- {
- strCmd += " WHERE " + whereStr;
- }
- cmd.CommandText = strCmd;
- cmd.CommandType = CommandType.Text;
- cmd.Parameters.Clear();
- if (parms != null)
- {
- foreach (var kvp in parms)
- {
- AddWithValue(cmd, kvp.Key, kvp.Value);
- }
- }
- using (var reader = cmd.ExecuteReader())
- {
- if (!reader.Read())
- {
- return 0;
- }
- GetValue(reader, Modle, propertyies);
- return 1;
- }
- }
- public static int SelectOne<TCommand, T>(TCommand cmd, T modle, string fields = "*") where TCommand : DbCommand
- {
- // 查找非空主键
- var fpkpropertyies = GetNotNullProperties(modle);
- // 生成语句
- var propertyies = GetProperties(typeof(T), fields);
- if (propertyies.Count == 0)
- {
- propertyies = new List<PropertyInfo>(GetProperties(typeof(T)).Values);
- }
- var strCmd = string.Empty;
- foreach (var propertyInfo in propertyies)
- {
- if (string.IsNullOrEmpty(strCmd))
- {
- strCmd = propertyInfo.Name;
- }
- else
- {
- strCmd += "," + propertyInfo.Name;
- }
- }
- strCmd = "SELECT " + strCmd + " FROM " + typeof(T).Name;
- strCmd += string.Format(" WHERE {0}=@{0}", fpkpropertyies[0].Name);
- for (int i = 1; i < fpkpropertyies.Count; i++)
- {
- strCmd += string.Format(" AND {0}=@{0}", fpkpropertyies[i].Name);
- }
- cmd.CommandText = strCmd;
- cmd.CommandType = CommandType.Text;
- cmd.Parameters.Clear();
- foreach (var property in fpkpropertyies)
- {
- object value = property.GetGetMethod().Invoke(modle, null);
- AddWithValue(cmd, "@" + property.Name, value);
- }
- using (var reader = cmd.ExecuteReader())
- {
- if (!reader.Read())
- {
- return 0;
- }
- GetValue(reader, modle, propertyies);
- return 1;
- }
- }
- /// <summary>
- /// 查找非空主键
- /// </summary>
- /// <typeparam name="T"></typeparam>
- /// <param name="modle"></param>
- /// <returns></returns>
- private static IList<PropertyInfo> GetNotNullProperties<T>(T modle)
- {
- var pks = GetPKs(typeof(T));
- if (pks == null || pks.Length == 0)
- {
- throw new Exception(string.Format("模型类{0}没有定义主键", typeof(T).FullName));
- }
- IList<PropertyInfo> fpkpropertyies = null;
- foreach (var pk in pks)
- {
- if (string.IsNullOrEmpty(pk))
- {
- throw new Exception(string.Format("模型类{0}的主键不能为空", typeof(T).FullName));
- }
- var withnullpk = false;
- var pkproperties = GetProperties(typeof(T), pk);
- if (pkproperties.Count == 0)
- {
- throw new Exception(string.Format("模型类{0}的主键与字段名不符", typeof(T).FullName));
- }
- foreach (var propertyInfo in pkproperties)
- {
- var getMethod = propertyInfo.GetGetMethod();
- var value = getMethod.Invoke(modle, null);
- if (value == null)
- {
- withnullpk = true;
- break;
- }
- }
- if (!withnullpk)
- {
- fpkpropertyies = pkproperties;
- break;
- }
- }
- if (fpkpropertyies == null)
- {
- throw new Exception("转入模型主键为空");
- }
- return fpkpropertyies;
- }
- public static int Delete<TCommand, T>(TCommand cmd, T modle) where TCommand : DbCommand
- {
- var fpkpropertyies = GetNotNullProperties(modle);
- var strCmd = string.Empty;
- strCmd = "DELETE FROM " + typeof(T).Name;
- strCmd += string.Format(" WHERE {0}=@{0}", fpkpropertyies[0].Name);
- for (int i = 1; i < fpkpropertyies.Count; i++)
- {
- strCmd += string.Format(" AND {0}=@{0}", fpkpropertyies[i].Name);
- }
- cmd.CommandText = strCmd;
- cmd.CommandType = CommandType.Text;
- cmd.Parameters.Clear();
- foreach (var property in fpkpropertyies)
- {
- object value = property.GetGetMethod().Invoke(modle, null);
- AddWithValue(cmd, "@" + property.Name, value);
- }
- return cmd.ExecuteNonQuery();
- }
- /// <summary>
- /// 异构对象插入数据库
- /// </summary>
- public static int Insert<TCommand, T>(TCommand cmd, string tablename, Dictionary<string, string> maps, T modle, string fields = "*") where TCommand : DbCommand
- {
- if (string.IsNullOrEmpty(tablename))
- {
- tablename = typeof(T).Name;
- }
- // DONE: 处理大小写问题
- var targetfields = GetTargetMaps<T>(maps, fields);
- cmd.CommandType = CommandType.Text;
- cmd.Parameters.Clear();
- string tablefields = string.Empty;
- string valuefields = string.Empty;
- foreach (var targetfield in targetfields)
- {
- if (string.IsNullOrEmpty(tablefields))
- {
- tablefields = targetfield.Key;
- valuefields = "@" + targetfield.Key;
- }
- else
- {
- tablefields += "," + targetfield.Key;
- valuefields += ",@" + targetfield.Key;
- }
- AddWithValue(cmd, "@" + targetfield.Key, targetfield.Value.GetGetMethod().Invoke(modle, null));
- }
- if (string.IsNullOrEmpty(tablefields))
- {
- throw new Exception("没有一个有效插入字段");
- }
- cmd.CommandText = string.Format("INSERT INTO {0}({1}) VALUES({2})", tablename, tablefields, valuefields);
- try
- {
- return cmd.ExecuteNonQuery();
- }
- catch (Exception ex)
- {
- Trace.Write(ex.ToString());
- Trace.Write(ModleToString(modle));
- throw;
- }
- }
- public static int Insert<TCommand, T>(TCommand cmd, T modle, string fields = "*") where TCommand : DbCommand
- {
- return Insert(cmd, null, null, modle, fields);
- ; }
- private static Dictionary<string, PropertyInfo> GetTargetMaps<T>(IDictionary<string, string> maps, string fields)
- {
- var newmaps = new Dictionary<string, string>();
- if (maps != null)
- {
- foreach (var map in maps)
- {
- newmaps[map.Key.Trim().ToLower()] = map.Value.Trim().ToLower();
- }
- }
- var targetfields = new Dictionary<string, PropertyInfo>();
- var orgfields = GetProperties(typeof (T));
- string[] arr_fields;
- if (fields.Equals("*"))
- {
- arr_fields = orgfields.Keys.ToArray();
- }
- else
- {
- arr_fields = fields.Split(',');
- }
- foreach (var field in arr_fields)
- {
- var key = field.Trim().ToLower();
- if (targetfields.ContainsKey(key))
- {
- continue;
- }
- if (newmaps.ContainsKey(key) && orgfields.ContainsKey(newmaps[key]))
- {
- targetfields[key] = orgfields[newmaps[key]];
- }
- else if (orgfields.ContainsKey(key))
- {
- targetfields[key] = orgfields[key];
- }
- }
- return targetfields;
- }
- public static int Update<TCommand, T>(TCommand cmd, string tablename, Dictionary<string, string> maps, T modle, string pkfields, string fields = "*") where TCommand : DbCommand
- {
- // DONE: 处理大小写问题
- var pkfields_dir = GetTargetMaps<T>(maps, pkfields);
- var targetfields = GetTargetMaps<T>(maps, fields);
- cmd.CommandType = CommandType.Text;
- cmd.Parameters.Clear();
- string keyFields = string.Empty;
- foreach (var targetfield in pkfields_dir)
- {
- if (string.IsNullOrEmpty(keyFields))
- {
- keyFields = string.Format("{0} = @{0}", targetfield.Key);
- }
- else
- {
- keyFields += string.Format(" AND {0} = @{0}", targetfield.Key);
- }
- AddWithValue(cmd, "@" + targetfield.Key, targetfield.Value.GetGetMethod().Invoke(modle, null));
- }
- if (string.IsNullOrEmpty(keyFields))
- {
- throw new Exception("没有一个有效的条件字段");
- }
- string setFields = string.Empty;
- foreach (var targetfield in targetfields)
- {
- if (string.IsNullOrEmpty(setFields))
- {
- setFields = string.Format("{0} = @{0}", targetfield.Key);
- }
- else
- {
- setFields += string.Format(", {0} = @{0}", targetfield.Key);
- }
- AddWithValue(cmd, "@" + targetfield.Key, targetfield.Value.GetGetMethod().Invoke(modle, null));
- }
- if (string.IsNullOrEmpty(setFields))
- {
- throw new Exception("没有一个有效更新字段");
- }
- cmd.CommandText = string.Format("UPDATE {0} SET {1} WHERE {2}", tablename, setFields, keyFields);
- try
- {
- return cmd.ExecuteNonQuery();
- }
- catch (Exception ex)
- {
- Trace.Write(ex.ToString());
- Trace.Write(ModleToString(modle));
- throw;
- }
- }
- public static int Update<TCommand, T>(TCommand cmd, T modle, string fields = "*") where TCommand : DbCommand
- {
- var pks = GetPKs(typeof(T));
- if (pks == null || pks.Length == 0)
- {
- throw new Exception(string.Format("当前类{0}没有定义关键字段", typeof(T).Name));
- }
- var pkfields = pks[0];
- if (pks.Length > 0)
- {
- foreach (var pk in pks)
- {
- if (string.IsNullOrEmpty(pk))
- {
- throw new Exception(string.Format("模型类{0}的主键不能为空", typeof(T).FullName));
- }
- var withnullpk = false;
- var pkproperties = GetProperties(typeof(T), pk);
- if (pkproperties.Count == 0)
- {
- throw new Exception(string.Format("模型类{0}的主键与字段名不符", typeof(T).FullName));
- }
- foreach (var propertyInfo in pkproperties)
- {
- var getMethod = propertyInfo.GetGetMethod();
- var value = getMethod.Invoke(modle, null);
- if (value == null)
- {
- withnullpk = true;
- break;
- }
- }
- if (!withnullpk)
- {
- pkfields = pk;
- break;
- }
- }
- }
-
- return Update(cmd, typeof (T).Name, null, modle, pkfields, fields);
- }
- public static int InsertOrUpdate<TCommand, T>(TCommand cmd, T modle, string fields = "*") where TCommand : DbCommand
- {
- try
- {
- // 查找非空主键
- var ifinsert = false;
- var pks = GetPKs(typeof(T));
- if (pks == null || pks.Length == 0)
- {
- ifinsert = true;
- }
- IList<PropertyInfo> fpkpropertyies = null;
- if (!ifinsert)
- {
- foreach (var pk in pks)
- {
- if (string.IsNullOrEmpty(pk))
- {
- throw new Exception(string.Format("模型类{0}的主键不能为空", typeof(T).FullName));
- }
- var withnullpk = false;
- var pkproperties = GetProperties(typeof(T), pk);
- if (pkproperties.Count == 0)
- {
- throw new Exception(string.Format("模型类{0}的主键与字段名不符", typeof(T).FullName));
- }
- foreach (var propertyInfo in pkproperties)
- {
- var getMethod = propertyInfo.GetGetMethod();
- var value = getMethod.Invoke(modle, null);
- if (value == null)
- {
- withnullpk = true;
- break;
- }
- }
- if (!withnullpk)
- {
- fpkpropertyies = pkproperties;
- break;
- }
- }
- if (fpkpropertyies == null)
- {
- ifinsert = true;
- }
- }
- List<PropertyInfo> propertyies = null;
- if (!ifinsert)
- {
- // 按主键更新
- propertyies = GetProperties(typeof(T), fields);
- if (propertyies.Count == 0)
- {
- propertyies = new List<PropertyInfo>(GetProperties(typeof(T)).Values);
- }
- var pknames = new HashSet<string>();
- foreach (var fpk in fpkpropertyies)
- {
- pknames.Add(fpk.Name);
- }
- for (int i = propertyies.Count - 1; i >= 0; i--)
- {
- if (pknames.Contains(propertyies[i].Name))
- {
- propertyies.RemoveAt(i);
- }
- }
- if (propertyies.Count == 0)
- {
- string strCmd = string.Format("SELECT COUNT(0) FROM " + typeof(T).Name + " WHERE {0}=@{0}", fpkpropertyies[0].Name);
- for (int i = 1; i < fpkpropertyies.Count; i++)
- {
- strCmd += string.Format(" AND {0}=@{0}", fpkpropertyies[i].Name);
- }
- cmd.CommandText = strCmd;
- cmd.CommandType = CommandType.Text;
- cmd.Parameters.Clear();
- foreach (var pk in fpkpropertyies)
- {
- object value = pk.GetGetMethod().Invoke(modle, null);
- AddWithValue(cmd, "@" + pk.Name, value);
- }
- var cnt = Convert.ToUInt32(cmd.ExecuteScalar());
- if (cnt == 0)
- {
- ifinsert = true;
- }
- }
- else
- {
- string strCmd = string.Format("UPDATE " + typeof(T).Name + " SET {0}=@{0}", propertyies[0].Name);
- for (int i = 1; i < propertyies.Count; i++)
- {
- strCmd += string.Format(",{0}=@{0}", propertyies[i].Name);
- }
- strCmd += string.Format(" WHERE {0}=@{0}", fpkpropertyies[0].Name);
- for (int i = 1; i < fpkpropertyies.Count; i++)
- {
- strCmd += string.Format(" AND {0}=@{0}", fpkpropertyies[i].Name);
- }
- cmd.CommandText = strCmd;
- cmd.CommandType = CommandType.Text;
- cmd.Parameters.Clear();
- foreach (var pk in fpkpropertyies)
- {
- object value = pk.GetGetMethod().Invoke(modle, null);
- AddWithValue(cmd, "@" + pk.Name, value);
- }
- foreach (var field in propertyies)
- {
- object value = field.GetGetMethod().Invoke(modle, null);
- AddWithValue(cmd, "@" + field.Name, value);
- }
- var cnt = cmd.ExecuteNonQuery();
- if (cnt == 0)
- {
- ifinsert = true;
- }
- else
- {
- return cnt;
- }
- }
- }
- if (ifinsert)
- {
- // 插入
- if (propertyies == null) // 只有在无主键的情况下才会为空
- {
- propertyies = GetProperties(typeof(T), fields);
- if (propertyies.Count == 0)
- {
- propertyies = new List<PropertyInfo>(GetProperties(typeof(T)).Values);
- }
- }
- if (fpkpropertyies != null)
- {
- propertyies.AddRange(fpkpropertyies);
- }
- if (propertyies.Count == 0)
- {
- throw new Exception(string.Format("模型{0}没有字段定义", typeof(T).FullName));
- }
- string strCmd = string.Format("INSERT INTO " + typeof(T).Name + "({0}", propertyies[0].Name);
- for (int i = 1; i < propertyies.Count; i++)
- {
- strCmd += string.Format(",{0}", propertyies[i].Name);
- }
- strCmd += string.Format(") VALUES(@{0}", propertyies[0].Name);
- for (int i = 1; i < propertyies.Count; i++)
- {
- strCmd += string.Format(",@{0}", propertyies[i].Name);
- }
- strCmd += ")";
- cmd.CommandText = strCmd;
- cmd.CommandType = CommandType.Text;
- cmd.Parameters.Clear();
- foreach (var field in propertyies)
- {
- object value = field.GetGetMethod().Invoke(modle, null);
- AddWithValue(cmd, "@" + field.Name, value);
- }
- return cmd.ExecuteNonQuery();
- }
- return 0;
- }
- catch (Exception ex)
- {
- Trace.Write(ex.ToString());
- Trace.Write(ModleToString(modle));
- throw;
- }
- }
- private static object ModleToString(object modle)
- {
- if (modle == null)
- {
- return "{}";
- }
- var list = GetProperties(modle.GetType()).Values;
- StringBuilder rslt = new StringBuilder();
- rslt.Append(modle.GetType().ToString() + ":{");
- bool hasone = false;
- foreach (var pro in list)
- {
- var getMethod = pro.GetGetMethod();
- if (getMethod == null)
- {
- continue;
- }
- var value = getMethod.Invoke(modle, null);
- var curent = string.Format("{0}:\"{1}\"", pro.Name, value ?? "nil");
- if (!hasone)
- {
- rslt.Append(curent);
- hasone = true;
- }
- else
- {
- rslt.Append("," + curent);
- }
- }
- rslt.Append("}");
- return rslt.ToString();
- }
- private static List<PropertyInfo> GetProperties(Type type, string outputFields)
- {
- List<PropertyInfo> rslt = new List<PropertyInfo>();
- Dictionary<string, PropertyInfo> properties = GetProperties(type);
- string[] fields = outputFields.Split(',');
- foreach (string field in fields)
- {
- string key = field.Trim().ToLower();
- if (properties.ContainsKey(key))
- {
- rslt.Add(properties[key]);
- }
- }
- return rslt;
- }
- private static Dictionary<Type, Dictionary<string, PropertyInfo>> _typeinfoCache = new Dictionary<Type, Dictionary<string, PropertyInfo>>();
- private static object _syncRoot_typeinfoCache = new object();
- private static Dictionary<string, PropertyInfo> GetProperties(Type type)
- {
- lock (_syncRoot_typeinfoCache)
- {
- if (_typeinfoCache.ContainsKey(type))
- {
- return _typeinfoCache[type];
- }
- PropertyInfo[] properties = type.GetProperties();
- Dictionary<string, PropertyInfo> dirProperties = new Dictionary<string, PropertyInfo>();
- foreach (PropertyInfo property in properties)
- {
- string key = property.Name.Trim().ToLower();
- if (!dirProperties.ContainsKey(key))
- {
- dirProperties[key] = property;
- }
- }
- _typeinfoCache[type] = dirProperties;
- return dirProperties;
- }
- }
- private static Dictionary<Type, ISqlEngine> _cmd_engines = new Dictionary<Type, ISqlEngine>();
- private static object _eng_root = new object();
- public static void Add<T>(SqlEngine<T> engine) where T : DbCommand
- {
- if (engine == null)
- {
- throw new Exception("engine参数不能为null");
- }
- lock (_eng_root)
- {
- _cmd_engines[typeof(T)] = engine;
- }
- }
- private static ISqlEngine GetEngine(Type type)
- {
- lock (_eng_root)
- {
- if (!_cmd_engines.ContainsKey(type))
- {
- throw new Exception(string.Format("{0}未关联数据库引擎", type.FullName));
- }
- return _cmd_engines[type];
- }
- }
- }
- }
|