internal void Execute(params object[] args) { string @class; if (!InstanceTable.ContainsKey((@class = this.ValidateArgs(args)))) { lock (InstanceTable.SyncRoot) { if (!InstanceTable.ContainsKey(@class)) { using (var writer = new StringWriter(CultureInfo.InvariantCulture)) using (var reader = this.DataProvider.ExecuteReader(this.CommandBehavior)) { var builder = new ClassBuilder(Namespace, @class, MemberAttributes.Static); AddExternalAssemblyReferences(builder, args); builder.AddImport("System"); builder.AddImport("System.Collections"); builder.AddImport("System.Data"); builder.AddImport("System.Globalization"); var method = builder.CreateMethod(MethodName, typeof(bool), MemberAttributes.Static); builder.AddParameter(method, typeof(DbDataReader), "reader"); builder.AddParameter(method, typeof(object[]), "args"); var counter = 0; writer.WriteLine("// reads data from \"{0}\" procedure.", this.DataProvider.CommandText); writer.WriteLine(); do { if ((args.Length - 1) < counter) continue; var schemaTable = reader.GetSchemaTable(); var argType = args[counter].GetType(); string instanceName = null; if (args[counter] is IEnumerable) { var genericType = argType.GetGenericArguments()[0]; writer.WriteLine("IList list{0} = args[{1}] as IList;", counter, counter); writer.WriteLine(""); writer.WriteLine("while (reader.Read())"); writer.WriteLine("{"); if (IsNativeType(genericType)) { WriteNativeDataTypeReaderLogic(writer, schemaTable, genericType); } else { instanceName = ValidateInstanceName(genericType); writer.WriteLine("{0} {1} = new {2}();", instanceName, ItemName, instanceName); WriteCommonDataReaderLogic(writer, schemaTable, genericType, null, null, ItemName); } writer.WriteLine("list{0}.Add(item);", counter); writer.WriteLine("}"); } else { instanceName = ValidateInstanceName(argType); writer.WriteLine("if (reader.Read())"); writer.WriteLine("{"); writer.WriteLine("{0} {1} = ({2})args[{3}];", instanceName, ItemName, instanceName, counter); WriteCommonDataReaderLogic(writer, schemaTable, argType, null, null, ItemName); writer.WriteLine("}"); } if ((counter + 1) != args.Length) { writer.WriteLine("if (!reader.NextResult())"); writer.WriteLine("{"); writer.WriteLine("return true;"); writer.WriteLine("}"); } counter++; } while (reader.NextResult()); writer.WriteLine("return true;"); builder.AddMethodBody(method, writer.ToString()); #if DEBUG using (var writer2 = new StringWriter(CultureInfo.InvariantCulture)) { builder.Write(writer2); System.Diagnostics.Debug.WriteLine(writer2.ToString()); } #endif object instance; if ((instance = builder.GetInstance()) == null) { throw new ArgumentException(string.Format(CultureInfo.InvariantCulture, "ClassBuilder failed to create the instance for a stored procedure {0}.", this.DataProvider.CommandText)); } InstanceTable.Add(@class, instance); } } } } this.Execute(@class, args); }
private static void AddExternalAssemblyReferences(ClassBuilder builder, object[] args) { builder.AddReference(Assembly.GetExecutingAssembly()); foreach (var item in args) { var type = item.GetType(); if (IsNativeType(type)) continue; if (item is IEnumerable) { type = type.GetGenericArguments()[0]; } builder.AddReference(Assembly.GetAssembly(type)); } }