/// <summary> /// 根据实体,插入数据,返回执行结果 /// </summary> /// <param name="Entity">实体</param> /// <returns>影响数</returns> public static int Insert(T Entity) { Entity.Validate(); var props = MemberInfoEx.GetPropertyCache <T>(); return(DBHelper.RunSql(_InsertSql, props.Select(x => DBHelper.AddDbParameter(x.Name, x.FastGetValue(Entity))).ToArray())); }
/// <summary> /// 根据实体,更新数据,返回执行结果 /// </summary> /// <param name="Entity">实体</param> /// <returns>影响数</returns> public static int UpdateEx(T Entity) { Entity.Validate(); var props = MemberInfoEx.GetPropertyCache <T>(); return(DBHelper.RunSql(_UpdateSql + "Where fGuid = @Uid", props.Select(x => DBHelper.AddDbParameter(x.Name, x.FastGetValue(Entity))).ToArray())); }
/// <summary> /// 生成查询SQL /// </summary> /// <returns>查询sql语句</returns> internal string SelectSql() { List <PropertyInfo> props = MemberInfoEx.GetPropertyCache <T>(); string sql = $"SELECT {string.Join(",", props.Select(x => $"{ x.GetCustomName() + "\r\n"}"))} \r\n" + $"FROM {typeof(T).GetCustomName()}" + "\r\n"; return(sql); }
/// <summary> /// 更新 /// </summary> /// <param name="entity">实体</param> /// <returns></returns> public static WhereHelper <T> Update(T entity) { entity.Validate(); WhereHelper <T> wherehelper = new WhereHelper <T>(); List <PropertyInfo> properties = MemberInfoEx.GetPropertyCache <T>(); properties.ForEach(x => wherehelper.ParaAppend(x.Name, x.FastGetValue(entity), false)); return(wherehelper.StringAppend(_UpdateSql, " WHERE ")); }
/// <summary> /// /生成更新SQL /// </summary> /// <returns>更新SQL</returns> public string UpdateSql() { var props = MemberInfoEx.GetPropertyCache <T>() .Where(x => !x.Name.Equals("Creator", StringComparison.OrdinalIgnoreCase) && !x.Name.Equals("CreateTime", StringComparison.OrdinalIgnoreCase) && !x.Name.Equals("Uid", StringComparison.OrdinalIgnoreCase)); string sql = $"UPDATE {typeof(T).GetCustomName()} \r\n" + $"SET {string.Join(",", props.Select(x => x.GetCustomName() + "= @" + x.Name + "\r\n"))}" + "\r\n"; return(sql); }
public void CanWriteWorks() { var t = typeof(Test); Assert.True(MemberInfoEx.CanWrite(t.Field("F1"))); Assert.False(MemberInfoEx.CanWrite(t.Field("F2"))); Assert.True(MemberInfoEx.CanWrite(t.Field("F3"))); Assert.False(t.Property("P1").CanWrite()); Assert.True(t.Property("P2").CanWrite()); Assert.True(t.Property("P3").CanWrite()); Assert.False(t.Method("M1").CanWrite()); Assert.False(t.Method("SetM1").CanWrite()); }
/// <summary> /// 生成插入SQL /// </summary> /// <returns>插入sql语句</returns> public string InsertSql() { var props = MemberInfoEx.GetPropertyCache <T>() .Where(x => !x.Name.Equals("Modifier", StringComparison.OrdinalIgnoreCase) && !x.Name.Equals("ModifyTime", StringComparison.OrdinalIgnoreCase)); string sql = $"INSERT INTO {typeof(T).GetCustomName()}\r\n" + $"(\r\n" + $"{string.Join(",", props.Select(x => x.GetCustomName() + "\r\n"))}" + $")\r\n" + $"values({string.Join(",", props.Select(x => $"@{x.Name}"))})" + "\r\n"; return(sql); }
/// <summary> /// 根据DataTable,方法中自动获取变化数据更新数据库 /// </summary> /// <param name="dt">内存数据</param> /// <param name="isChange">是否为变化数据</param> /// <returns></returns> public static bool Save(DataTable dt, bool isChange = false) { DataTable dtChanges = null; if (isChange) { dtChanges = dt; } else { dtChanges = dt.GetChanges(); } if (dtChanges == null || dtChanges.Rows.Count == 0) { return(true); } List <string> listSqls = new List <string>(); List <PropertyInfo> properties; List <List <DbParameter> > listDbParas = new List <List <DbParameter> >(); foreach (DataRow dr in dtChanges.Rows) { dr.Validate <T>(); switch (dr.RowState) { case DataRowState.Added: listSqls.Add(_InsertSql); properties = MemberInfoEx.GetPropertyCache <T>(); dr["fCreator"] = Environment.MachineName; dr["fCreateTime"] = DateTime.Now; listDbParas.Add(properties.Select(x => DBHelper.AddDbParameter(x.Name, dr[x.GetCustomName()])).ToList()); break; case DataRowState.Deleted: listSqls.Add(_DeleteSql + $" WHERE fGuid = '{dr["fGuid", DataRowVersion.Original]}'"); listDbParas.Add(new List <DbParameter>()); break; case DataRowState.Modified: listSqls.Add(_UpdateSql + $" WHERE fGuid ='{dr["fGuid"]}'"); properties = MemberInfoEx.GetPropertyCache <T>(); dr["fModifier"] = Environment.MachineName; dr["fModifyTime"] = DateTime.Now; listDbParas.Add(properties.Select(x => DBHelper.AddDbParameter(x.Name, dr[x.GetCustomName()])).ToList()); break; default: break; } } bool Result = DBHelper.RunSql(listSqls, listDbParas); if (Result) { dt.AcceptChanges(); } return(Result); }
static void GenInterfaceOrStructOrClass(Type type, TypeStatus ts, Func <Type, TypeStatus> getParent, Action <Type> onNewType) { TextFile tfFile = null; if (type.DeclaringType != null) { ts.IsInnerType = true; TypeStatus tsParent = getParent(type.DeclaringType); if (tsParent == null || tsParent.status == TypeStatus.Status.Wait) { if (tsParent == null) { onNewType(type.DeclaringType); } return; } if (tsParent.status == TypeStatus.Status.Ignored) { ts.status = TypeStatus.Status.Ignored; return; } tfFile = tsParent.tf.FindByTag("epos"); } if (tfFile == null) { tfFile = new TextFile(); } ts.tf = tfFile; ts.status = TypeStatus.Status.Exported; GeneratorHelp.ATypeInfo ti = GeneratorHelp.CreateTypeInfo(type); StringBuilder sb = new StringBuilder(); TextFile tfNs = tfFile; //string dir = Dir; // // ignore Experimental @eugenejiang // if (type.Namespace != null && type.Namespace.IndexOf("UnityEngine.Experimental.") >= 0) { // return; // } if (type.DeclaringType == null && !string.IsNullOrEmpty(type.Namespace)) { tfNs = tfFile.Add("namespace {0}", type.Namespace).BraceIn(); tfNs.BraceOut(); } GenAttributeForClassIfNeeded(type, tfNs); // multiple attributes // tfNs.Add("[Bridge.External]"); TextFile tfClass = null; sb.Remove(0, sb.Length); { // force public if (type.IsPublic || type.IsNestedPublic || type.IsNested || type.IsNestedFamily) { sb.Append("public "); } // if (type.IsNestedFamily) { // sb.Append("protected "); // } // if (type.FullName.IndexOf("DropdownItem") >= 0) { // Debug.Assert(false); // } if (type.IsClass) { if (type.IsAbstract && type.IsSealed) { sb.Append("static "); } //else if (type.IsAbstract) // sb.Append("abstract "); //else if (type.IsSealed) // sb.Append("sealed "); //if (type.is) } if (type.IsInterface) { sb.Append("interface "); } else if (type.IsValueType) { sb.Append("struct "); } else { sb.Append("class "); } string className = type.CsFullName(CsNameOption.CompilableWithT); int dot = className.LastIndexOf("."); if (dot >= 0) { className = className.Substring(dot + 1); } sb.Append(className); Type vBaseType = type.ValidBaseType(); Type[] interfaces = type.GetDeclaringInterfaces(); if (vBaseType != null || interfaces.Length > 0) { sb.Append(" : "); args a = new args(); if (vBaseType != null) { a.Add(typefn(vBaseType, type.Namespace, CsNameOption.CompilableWithT)); onNewType(vBaseType); } foreach (var i in interfaces) { a.Add(typefn(i, type.Namespace, CsNameOption.CompilableWithT)); onNewType(i); } sb.Append(a.ToString()); } tfClass = tfNs.Add(sb.ToString()).BraceIn(); tfClass.BraceOut(); } tfClass.AddTag("epos"); if (handleEvents(tfClass, type, onNewType)) { tfClass.AddLine(); } for (int i = 0; i < ti.Fields.Count; i++) { MemberInfoEx infoEx = ti.Fields[i]; FieldInfo field = infoEx.member as FieldInfo; var publicOrProtected = "public"; if (field.IsFamily) { // publicOrProtected = "protected"; } if (field.IsLiteral && !field.IsInitOnly) { { var attributes = field.GetCustomAttributes(); foreach (var attr in attributes) { tfClass.Add("[{0}]", attr.GetType().Name); onNewType(attr.GetType()); } } if ("string" == typefn(field.FieldType, type.Namespace)) { tfClass.Add(publicOrProtected + " const {0} {1} = \"{2}\";", typefn(field.FieldType, type.Namespace), field.Name, field.GetValue(null)); } else if ("float" == typefn(field.FieldType, type.Namespace)) { var fv = (float)field.GetValue(null); string defaultvalue; if (float.IsNaN(fv)) { defaultvalue = "float.NaN"; } else if (float.IsPositiveInfinity(fv)) { defaultvalue = "float.PositiveInfinity"; } else if (float.IsNegativeInfinity(fv)) { defaultvalue = "float.NegativeInfinity"; } else { defaultvalue = fv + "f"; } tfClass.Add(publicOrProtected + " const {0} {1} = {2};", typefn(field.FieldType, type.Namespace), field.Name, defaultvalue); } else { tfClass.Add(publicOrProtected + " const {0} {1} = {2};", typefn(field.FieldType, type.Namespace), field.Name, field.GetValue(null)); } } else { tfClass.Add(publicOrProtected + " {0}{1} {2};", (field.IsStatic ? "static " : ""), typefn(field.FieldType, type.Namespace), field.Name); } onNewType(field.FieldType); } if (ti.Fields.Count > 0) { tfClass.AddLine(); } // Constructors for (int i = 0; i < ti.Cons.Count; i++) { MemberInfoEx infoEx = ti.Cons[i]; ConstructorInfo con = infoEx.member as ConstructorInfo; if (type.IsValueType) { // 结构体不需要无参数构造函数 if (con == null || con.GetParameters().Length == 0) { continue; } } string ctorName = type.Name; if (type.IsGenericTypeDefinition) { int flag = ctorName.LastIndexOf('`'); if (flag >= 0) { ctorName = ctorName.Substring(0, flag); } } var constructorBuilder = new StringBuilder(); var paras = con == null ? "" : Ps2String(type, con.GetParameters()); constructorBuilder.Append($"public {ctorName}({paras})"); var baseType = type.ValidBaseType(); if (baseType != null && !HasDefaultConstructor(baseType)) { constructorBuilder.Append($" : base({BaseConstructorParameters(baseType)})"); } constructorBuilder.Append(" { throw new Exception(\"not impl\"); }"); tfClass.Add(constructorBuilder.ToString()); if (con != null) { foreach (var p in con.GetParameters()) { onNewType(p.ParameterType); } } } if (ti.Cons.Count > 0) { tfClass.AddLine(); } handlePros(tfClass, type, ti, onNewType); if (ti.Pros.Count > 0) { tfClass.AddLine(); } handleMethods(tfClass, type, ti, onNewType); if (!type.IsInterface) { handleInterfaceProblems(tfClass, type, onNewType); } }
static void handleMethods(TextFile tfClass, Type type, GeneratorHelp.ATypeInfo ti, Action <Type> OnNewType) { Action <MethodInfo> action = (method) => { bool hasExtensionAttribute = (method.GetCustomAttributes(typeof(System.Runtime.CompilerServices.ExtensionAttribute), false).Length > 0); ParameterInfo[] ps = method.GetParameters(); var paramsString = Ps2String(type, ps, hasExtensionAttribute); // if (paramsString.IndexOf("UnityEngine.Experimental.") >= 0) { // return; // } // ignore unsafe if (paramsString.IndexOf("*") >= 0) { return; } // DO NOT handle Finalize method if (method.Name == "Finalize") { return; } StringBuilder sbDef = new StringBuilder(); bool isI = type.IsInterface; if (!isI) { if (method.IsPublic) { sbDef.Append("public "); } else if (method.IsFamily) { sbDef.Append("public "); } // sbDef.Append("protected "); else if (method.IsAssembly) { sbDef.Append("public "); } // sbDef.Append("internal "); if (method.IsStatic) { sbDef.Append("static "); } // sbDef.Append("extern "); if (method.GetBaseDefinition() != method) { sbDef.Append("override "); } else if (!type.IsValueType && method.IsVirtual && !type.IsValueType) { sbDef.Append("virtual "); } } if (!(method.IsSpecialName && method.Name == "op_Implicit")) { sbDef.Append(typefn(method.ReturnType, type.Namespace, CsNameOption.CompilableWithT) + " "); } OnNewType(method.ReturnType); sbDef.Append(MethodNameString(type, method)); if (method.IsGenericMethodDefinition) { Type[] argus = method.GetGenericArguments(); args t_args = new args(); foreach (var a in argus) { t_args.Add(a.Name); } sbDef.Append(t_args.Format(args.ArgsFormat.GenericT)); } sbDef.Append("("); // bool hasExtensionAttribute = (method.GetCustomAttributes(typeof(System.Runtime.CompilerServices.ExtensionAttribute), false).Length > 0); // ParameterInfo[] ps = method.GetParameters(); { sbDef.Append(Ps2String(type, ps, hasExtensionAttribute)); sbDef.Append(")"); foreach (var p in ps) { OnNewType(p.ParameterType); } } sbDef.Append(!isI ? " { throw new Exception(\"not impl\"); }" : ";"); // tfClass.Add("[Bridge.Name(\"" + method.Name + "\")]"); tfClass.Add(sbDef.ToString()); }; bool hasSpecial = false; for (int i = 0; i < ti.Methods.Count; i++) { MemberInfoEx infoEx = ti.Methods[i]; MethodInfo method = infoEx.member as MethodInfo; if (method.IsSpecialName) { hasSpecial = true; action(method); } } if (hasSpecial) { tfClass.AddLine(); } for (int i = 0; i < ti.Methods.Count; i++) { MemberInfoEx infoEx = ti.Methods[i]; MethodInfo method = infoEx.member as MethodInfo; if (!method.IsSpecialName) { action(method); } } }
static void handleInterfaceProblems(TextFile tfClass, Type cType, Action <Type> OnNewType) { Type[] interfaces = cType.GetValidInterfaces(); Action <Type, MethodInfo> actionMethod = (iType, method) => { StringBuilder sbDef = new StringBuilder(); // sbDef.Append("extern "); if (!(method.IsSpecialName && method.Name == "op_Implicit")) { sbDef.Append(typefn(method.ReturnType, cType.Namespace, CsNameOption.CompilableWithT) + " "); } OnNewType(method.ReturnType); sbDef.Append(iType.CsFullName(CsNameOption.CompilableWithT) + "."); // 这句是重点 sbDef.Append(MethodNameString(cType, method)); if (method.IsGenericMethodDefinition) { Type[] argus = method.GetGenericArguments(); args t_args = new args(); foreach (var a in argus) { t_args.Add(a.Name); } sbDef.Append(t_args.Format(args.ArgsFormat.GenericT)); } sbDef.Append("("); ParameterInfo[] ps = method.GetParameters(); { sbDef.Append(Ps2String(cType, ps)); sbDef.Append(") { throw new Exception(\"Exception\"); }"); foreach (var p in ps) { OnNewType(p.ParameterType); } } tfClass.Add(sbDef.ToString()); }; Action <Type, PropertyInfo> actionPro = (iType, pro) => { OnNewType(pro.PropertyType); ParameterInfo[] ps = pro.GetIndexParameters(); args iargs = new args(); bool isIndexer = (ps.Length > 0); if (isIndexer) { for (int j = 0; j < ps.Length; j++) { iargs.AddFormat("{0} {1}", typefn(ps[j].ParameterType, cType.Namespace), ps[j].Name); OnNewType(ps[j].ParameterType); } } MethodInfo getm = pro.GetGetMethod(true); MethodInfo setm = pro.GetSetMethod(true); bool canGet = getm != null && getm.IsPublic; bool canSet = setm != null && setm.IsPublic; string getset = ""; { if (canGet) { getset += "get { throw new Exception(\"not impl\"); }"; } if (canSet) { getset += " set { throw new Exception(\"not impl\"); }"; } } string vo = string.Empty; if (isIndexer) { tfClass.Add("{4}{0} {1}{2} {{ {3} }}", typefn(pro.PropertyType, cType.Namespace), iType.CsFullName(CsNameOption.CompilableWithT) + ".this", // 这句是重点 iargs.Format(args.ArgsFormat.Indexer), getset, vo); } else { tfClass.Add("{3}{0} {1} {{ {2} }}", typefn(pro.PropertyType, cType.Namespace), iType.CsFullName(CsNameOption.CompilableWithT) + "." + // 这句是重点 pro.Name, getset, vo); } }; foreach (Type iType in interfaces) { GeneratorHelp.ATypeInfo ti = GeneratorHelp.CreateTypeInfo(iType); for (int i = 0; i < ti.Methods.Count; i++) { MemberInfoEx infoEx = ti.Methods[i]; MethodInfo method = infoEx.member as MethodInfo; actionMethod(iType, method); } for (int i = 0; i < ti.Pros.Count; i++) { MemberInfoEx infoEx = ti.Pros[i]; PropertyInfo pro = infoEx.member as PropertyInfo; actionPro(iType, pro); } // 特殊处理,BridgeProj工程 if (iType == typeof(ICollection)) { tfClass.Add("bool System.Collections.ICollection.IsReadOnly { get; }"); } } }
static void handlePros(TextFile tfClass, Type type, GeneratorHelp.ATypeInfo ti, Action <Type> OnNewType) { Action <PropertyInfo> action = (pro) => { // // ignore Experimental @eugenejiang // if (typefn(pro.PropertyType, type.Namespace).IndexOf("UnityEngine.Experimental.") >= 0) { // return; // } bool isI = type.IsInterface; OnNewType(pro.PropertyType); ParameterInfo[] ps = pro.GetIndexParameters(); args iargs = new args(); bool isIndexer = (ps.Length > 0); if (isIndexer) { for (int j = 0; j < ps.Length; j++) { iargs.AddFormat("{0} {1}", typefn(ps[j].ParameterType, type.Namespace), ps[j].Name); OnNewType(ps[j].ParameterType); } } MethodInfo getm = pro.GetGetMethod(true); MethodInfo setm = pro.GetSetMethod(true); bool canGet = getm != null && (getm.IsPublic || getm.IsFamily); bool canSet = setm != null && (setm.IsPublic || setm.IsFamily); string getset = ""; if (!isI) { if (canGet) { getset += string.Format("get {{ throw new Exception(\"not impl\"); }}", typefn(pro.PropertyType, type.Namespace)); } if (canSet) { getset += " set { throw new Exception(\"not impl\"); }"; } } else { if (canGet) { getset += "get;"; } if (canSet) { getset += " set;"; } } string vo = string.Empty; if (!isI) { vo = "public "; if ((getm != null && getm.IsStatic) || (setm != null && setm.IsStatic)) { vo += "static "; } if (!type.IsValueType) { if ((getm != null && getm.IsVirtual) || (setm != null && setm.IsVirtual)) { vo += ((getm != null && getm.GetBaseDefinition() != getm) || (setm != null && setm.GetBaseDefinition() != setm)) ? "override " : "virtual "; } } } if (isIndexer) { tfClass.Add("{3}{0} this{1} {{ {2} }}", typefn(pro.PropertyType, type.Namespace), iargs.Format(args.ArgsFormat.Indexer), getset, vo); } else { tfClass.Add("{3}{0} {1} {{ {2} }}", typefn(pro.PropertyType, type.Namespace), pro.Name, getset, vo); } }; bool hasNoneIndexer = false; for (int i = 0; i < ti.Pros.Count; i++) { MemberInfoEx infoEx = ti.Pros[i]; PropertyInfo pro = infoEx.member as PropertyInfo; if (pro.GetIndexParameters().Length == 0) { hasNoneIndexer = true; action(pro); } } if (hasNoneIndexer) { tfClass.AddLine(); } for (int i = 0; i < ti.Pros.Count; i++) { MemberInfoEx infoEx = ti.Pros[i]; PropertyInfo pro = infoEx.member as PropertyInfo; if (pro.GetIndexParameters().Length > 0) { action(pro); } } }