diff --git a/AmalgamationTool/DynamORM.Amalgamation.cs b/AmalgamationTool/DynamORM.Amalgamation.cs index 2c6c78a..6e7bc22 100644 --- a/AmalgamationTool/DynamORM.Amalgamation.cs +++ b/AmalgamationTool/DynamORM.Amalgamation.cs @@ -44,6 +44,7 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Collections.Specialized; using System.Collections; +using System.ComponentModel; using System.Data.Common; using System.Data; using System.Dynamic; @@ -1673,6 +1674,90 @@ namespace DynamORM public DbProviderFactory Provider { get { return _provider; } } /// Gets the procedures invoker. + /// + /// + /// using (var db = GetORM()) + /// { + /// db.Execute(@"CREATE OR ALTER PROCEDURE sp_Exp_Scalar AS SELECT 42;"); + /// var res0 = db.Procedures.sp_Exp_Scalar(); + /// var res1 = db.Procedures.sp_Exp_Scalar(); + /// + /// db.Execute(@"CREATE OR ALTER PROCEDURE sp_Exp_ReturnInt AS RETURN 42;"); + /// var res2 = db.Procedures.sp_Exp_ReturnInt(); + /// + /// db.Execute(@"CREATE OR ALTER PROCEDURE sp_Exp_SomeData AS + /// SELECT 1 Id, 'Some Name 1' [Name], 'Some Desc 1' [Desc], GETDATE() [Date] + /// UNION ALL SELECT 2 Id, 'Some Name 2', 'Some Desc 2', GETDATE() [Date];"); + /// var res3 = db.Procedures.sp_Exp_SomeData(); + /// var res4 = db.Procedures.sp_Exp_SomeData>(); + /// + /// db.Execute(@"CREATE OR ALTER PROCEDURE sp_Exp_SomeInputAndOutput + /// @Name nvarchar(50), + /// @Result nvarchar(256) OUTPUT + /// AS + /// SELECT @Result = 'Hi, ' + @Name + ' your lucky number is 42!';"); + /// var res5 = db.Procedures.sp_Exp_SomeInputAndOutput(Name: "G4g4r1n", out_Result: new DynamicColumn + /// { + /// Schema = new DynamicSchemaColumn + /// { + /// Size = 256, + /// }, + /// }, ret_Return: 0); + /// var res6 = db.Procedures.sp_Exp_SomeInputAndOutput(Name: "G4g4r1n", out_Result: new DynamicSchemaColumn + /// { + /// Size = 256, + /// }, ret_Return: 0); + /// + /// db.Execute(@"CREATE OR ALTER PROCEDURE sp_Exp_SomeInputAndOutputWithDataAndReturn + /// @Name nvarchar(50), + /// @Result nvarchar(256) OUTPUT + /// AS + /// SELECT @Result = 'Hi, ' + @Name + ' your lucky number is 42!' + /// + /// SELECT 1 Id, 'Some Name 1' [Name], 'Some Desc 1' [Desc], GETDATE() [Date] + /// UNION ALL SELECT 2 Id, 'Some Name 2', 'Some Desc 2', GETDATE() [Date] + /// + /// RETURN 42;"); + /// var res7 = db.Procedures.sp_Exp_SomeInputAndOutputWithDataAndReturn, sp_Exp_SomeInputAndOutputWithDataAndReturn_Result>(Name: "G4g4r1n", out_Result: new DynamicColumn + /// { + /// Schema = new DynamicSchemaColumn + /// { + /// Size = 256, + /// }, + /// }, ret_Return: 0); + /// var res8 = db.Procedures.sp_Exp_SomeInputAndOutputWithDataAndReturn, sp_Exp_SomeInputAndOutputWithDataAndReturn_Result>(Name: "G4g4r1n", out_Result: new DynamicSchemaColumn + /// { + /// Size = 256, + /// }, ret_Return: 0); + /// } + /// + ///private class sp_Exp_SomeData_Result + ///{ + /// public virtual int Id { get; set; } + /// public virtual string Name { get; set; } + /// public virtual string Desc { get; set; } + /// public virtual DateTime Date { get; set; } + ///} + ///private class sp_Exp_SomeInputAndOutput_Result + ///{ + /// public virtual string Result { get; set; } + /// public virtual string Return { get; set; } + ///} + ///private class sp_Exp_SomeInputAndOutputWithDataAndReturn_Result + ///{ + /// public class Data + /// { + /// public virtual int Id { get; set; } + /// public virtual string Name { get; set; } + /// public virtual string Desc { get; set; } + /// public virtual DateTime Date { get; set; } + /// } + /// public virtual List sp_Exp_SomeInputAndOutputWithDataAndReturn { get; set; } + /// public virtual string Result { get; set; } + /// public virtual string Return { get; set; } + ///} + /// + /// public dynamic Procedures { get @@ -1680,7 +1765,7 @@ namespace DynamORM if (_proc == null) { if ((Options & DynamicDatabaseOptions.SupportStoredProcedures) != DynamicDatabaseOptions.SupportStoredProcedures) - throw new InvalidOperationException("Database connection desn't support stored procedures."); + throw new InvalidOperationException("Database connection doesn't support stored procedures."); _proc = new DynamicProcedureInvoker(this); } @@ -5519,6 +5604,8 @@ namespace DynamORM #region Prepare arguments int alen = args.Length; + bool retIsAdded = false; + if (alen > 0) { for (int i = 0; i < alen; i++) @@ -5533,14 +5620,38 @@ namespace DynamORM { var dcv = (DynamicColumn)arg; - string paramName = dcv.Alias ?? dcv.ColumnName ?? + string paramName = i.ToString(); + bool isOut = false; + bool isRet = false; + bool isBoth = false; + + if (info.ArgumentNames.Count > i) + { + isOut = info.ArgumentNames[i].StartsWith("out_"); + isRet = info.ArgumentNames[i].StartsWith("ret_"); + isBoth = info.ArgumentNames[i].StartsWith("both_"); + + paramName = isOut || isRet ? + info.ArgumentNames[i].Substring(4) : + isBoth ? info.ArgumentNames[i].Substring(5) : + info.ArgumentNames[i]; + } + + paramName = dcv.Alias ?? dcv.ColumnName ?? (dcv.Schema.HasValue ? dcv.Schema.Value.Name : null) ?? - (info.ArgumentNames.Count > i ? info.ArgumentNames[i] : i.ToString()); + paramName; - bool isOut = dcv.ParameterDirection == ParameterDirection.Output || - dcv.ParameterDirection == ParameterDirection.ReturnValue; + if (!isOut && !isRet && !isBoth) + { + isOut = dcv.ParameterDirection == ParameterDirection.Output; + isRet = dcv.ParameterDirection == ParameterDirection.ReturnValue; + isBoth = dcv.ParameterDirection == ParameterDirection.InputOutput; + } - if (isOut || dcv.ParameterDirection == ParameterDirection.InputOutput) + if (isRet) + retIsAdded = true; + + if (isOut || isRet || isBoth) { if (retParams == null) retParams = new Dictionary(); @@ -5551,14 +5662,66 @@ namespace DynamORM { var ds = dcv.Schema.Value; cmd.AddParameter( - _db.GetParameterName(paramName), dcv.ParameterDirection, + _db.GetParameterName(paramName), + isOut ? ParameterDirection.Output : + isRet ? ParameterDirection.ReturnValue : + isBoth ? ParameterDirection.InputOutput : + ParameterDirection.Input, ds.Type, ds.Size, ds.Precision, ds.Scale, - isOut ? DBNull.Value : dcv.Value); + (isOut || isRet) ? DBNull.Value : dcv.Value); } else cmd.AddParameter( - _db.GetParameterName(paramName), dcv.ParameterDirection, - arg == null ? DbType.String : arg.GetType().ToDbType(), 0, isOut ? DBNull.Value : dcv.Value); + _db.GetParameterName(paramName), + isOut ? ParameterDirection.Output : + isRet ? ParameterDirection.ReturnValue : + isBoth ? ParameterDirection.InputOutput : + ParameterDirection.Input, + arg == null ? DbType.String : arg.GetType().ToDbType(), + isRet ? 4 : 0, + (isOut || isRet) ? DBNull.Value : dcv.Value); + } + else if (arg is DynamicSchemaColumn) + { + var dsc = (DynamicSchemaColumn)arg; + + string paramName = i.ToString(); + bool isOut = false; + bool isRet = false; + bool isBoth = false; + + if (info.ArgumentNames.Count > i) + { + isOut = info.ArgumentNames[i].StartsWith("out_"); + isRet = info.ArgumentNames[i].StartsWith("ret_"); + isBoth = info.ArgumentNames[i].StartsWith("both_"); + + paramName = isOut || isRet ? + info.ArgumentNames[i].Substring(4) : + isBoth ? info.ArgumentNames[i].Substring(5) : + info.ArgumentNames[i]; + } + + paramName = dsc.Name ?? paramName; + + if (isRet) + retIsAdded = true; + + if (isOut || isRet || isBoth) + { + if (retParams == null) + retParams = new Dictionary(); + retParams.Add(paramName, cmd.Parameters.Count); + } + + cmd.AddParameter( + _db.GetParameterName(paramName), + isOut ? ParameterDirection.Output : + isRet ? ParameterDirection.ReturnValue : + isBoth ? ParameterDirection.InputOutput : + ParameterDirection.Input, + dsc.Type, dsc.Size, dsc.Precision, dsc.Scale, + DBNull.Value); } else { @@ -5568,6 +5731,9 @@ namespace DynamORM bool isRet = info.ArgumentNames[i].StartsWith("ret_"); bool isBoth = info.ArgumentNames[i].StartsWith("both_"); + if (isRet) + retIsAdded = true; + string paramName = isOut || isRet ? info.ArgumentNames[i].Substring(4) : isBoth ? info.ArgumentNames[i].Substring(5) : @@ -5584,8 +5750,11 @@ namespace DynamORM _db.GetParameterName(paramName), isOut ? ParameterDirection.Output : isRet ? ParameterDirection.ReturnValue : - isBoth ? ParameterDirection.InputOutput : ParameterDirection.Input, - arg == null ? DbType.String : arg.GetType().ToDbType(), 0, isOut ? DBNull.Value : arg); + isBoth ? ParameterDirection.InputOutput : + ParameterDirection.Input, + arg == null ? isRet ? DbType.Int32 : DbType.String : arg.GetType().ToDbType(), + isRet ? 4 : 0, + (isOut || isRet) ? DBNull.Value : arg); } else cmd.AddParameter(_db, arg); @@ -5636,7 +5805,7 @@ namespace DynamORM cache = rdr.CachedReader(); while (cache.Read()) - listInstance.Add(cache[0] == DBNull.Value ? defVal : argType.CastObject(cache[0])); + listInstance.Add(cache[0] != null && cache[0] != DBNull.Value ? argType.CastObject(cache[0]) : defVal); mainResult = listInstance; } @@ -5653,7 +5822,7 @@ namespace DynamORM while (cache.Read()) { - if (cache[0] == DBNull.Value && Guid.TryParse(cache[0].ToString(), out Guid g)) + if (cache[0] != null && cache[0] != DBNull.Value && Guid.TryParse(cache[0].ToString(), out Guid g)) listInstance.Add(g); } @@ -5663,32 +5832,41 @@ namespace DynamORM { DynamicTypeMap mapper = DynamicMapperCache.GetMapper(argType); if (mapper == null) - throw new InvalidCastException(string.Format("Don't konw what to do with this type: '{0}'.", argType.ToString())); + throw new InvalidCastException(string.Format("Don't know what to do with this type: '{0}'.", argType.ToString())); IDataReader cache = null; using (IDataReader rdr = cmd.ExecuteReader()) cache = rdr.CachedReader(); - mainResult = cache.EnumerateReader().MapEnumerable(argType).ToList(); + var lt = typeof(List<>); + var ltc = lt.MakeGenericType(argType); + var instance = Activator.CreateInstance(ltc) as IList; + + foreach (var item in cache.EnumerateReader()) + instance.Add(DynamicExtensions.Map(item, argType)); + + mainResult = instance; + + //mainResult = cache.EnumerateReader().MapEnumerable(argType).ToList(); } } else if (types[0].IsValueType || types[0] == typeof(string)) { mainResult = cmd.ExecuteScalar(); - if (mainResult != DBNull.Value) + if (mainResult != null && mainResult != DBNull.Value) mainResult = types[0].CastObject(mainResult); } else if (types[0] == typeof(Guid)) { mainResult = cmd.ExecuteScalar(); - if (mainResult != DBNull.Value && Guid.TryParse(mainResult.ToString(), out Guid g)) + if (mainResult != null && mainResult != DBNull.Value && Guid.TryParse(mainResult.ToString(), out Guid g)) mainResult = g; } else { DynamicTypeMap mapper = DynamicMapperCache.GetMapper(types[0]); if (mapper == null) - throw new InvalidCastException(string.Format("Don't konw what to do with this type: '{0}'.", types[0].ToString())); + throw new InvalidCastException(string.Format("Don't know what to do with this type: '{0}'.", types[0].ToString())); using (IDataReader rdr = cmd.ExecuteReader()) if (rdr.Read()) @@ -5698,8 +5876,33 @@ namespace DynamORM } } else + { + var returnName = _db.GetParameterName("___result___"); + if (!retIsAdded) + cmd.AddParameter(returnName, ParameterDirection.ReturnValue, DbType.Int32, 4, 0, 0, DBNull.Value); + mainResult = cmd.ExecuteNonQuery(); + IDbDataParameter returnParam = null; + if (!retIsAdded) + returnParam = cmd.Parameters[returnName] as IDbDataParameter; + else + { + foreach (var e in cmd.Parameters) + { + var p = e as IDbDataParameter; + if (p != null && p.Direction == ParameterDirection.ReturnValue) + { + returnParam = p; + break; + } + } + } + + if (returnParam != null && returnParam.Value != null && returnParam.Value != DBNull.Value) + mainResult = returnParam.Value; + } + #endregion Get main result #region Handle out params diff --git a/DynamORM.Tests/DynamORM.Tests.csproj b/DynamORM.Tests/DynamORM.Tests.csproj index 8c51598..ca38ca4 100644 --- a/DynamORM.Tests/DynamORM.Tests.csproj +++ b/DynamORM.Tests/DynamORM.Tests.csproj @@ -118,10 +118,10 @@ - 3.1.1 + 3.3.1 - 3.1.1 + 3.3.1 1.0.118 diff --git a/DynamORM/DynamicDatabase.cs b/DynamORM/DynamicDatabase.cs index 95bbfe5..c5d641d 100644 --- a/DynamORM/DynamicDatabase.cs +++ b/DynamORM/DynamicDatabase.cs @@ -122,6 +122,90 @@ namespace DynamORM public DbProviderFactory Provider { get { return _provider; } } /// Gets the procedures invoker. + /// + /// + /// using (var db = GetORM()) + /// { + /// db.Execute(@"CREATE OR ALTER PROCEDURE sp_Exp_Scalar AS SELECT 42;"); + /// var res0 = db.Procedures.sp_Exp_Scalar(); + /// var res1 = db.Procedures.sp_Exp_Scalar(); + /// + /// db.Execute(@"CREATE OR ALTER PROCEDURE sp_Exp_ReturnInt AS RETURN 42;"); + /// var res2 = db.Procedures.sp_Exp_ReturnInt(); + /// + /// db.Execute(@"CREATE OR ALTER PROCEDURE sp_Exp_SomeData AS + /// SELECT 1 Id, 'Some Name 1' [Name], 'Some Desc 1' [Desc], GETDATE() [Date] + /// UNION ALL SELECT 2 Id, 'Some Name 2', 'Some Desc 2', GETDATE() [Date];"); + /// var res3 = db.Procedures.sp_Exp_SomeData(); + /// var res4 = db.Procedures.sp_Exp_SomeData>(); + /// + /// db.Execute(@"CREATE OR ALTER PROCEDURE sp_Exp_SomeInputAndOutput + /// @Name nvarchar(50), + /// @Result nvarchar(256) OUTPUT + /// AS + /// SELECT @Result = 'Hi, ' + @Name + ' your lucky number is 42!';"); + /// var res5 = db.Procedures.sp_Exp_SomeInputAndOutput(Name: "G4g4r1n", out_Result: new DynamicColumn + /// { + /// Schema = new DynamicSchemaColumn + /// { + /// Size = 256, + /// }, + /// }, ret_Return: 0); + /// var res6 = db.Procedures.sp_Exp_SomeInputAndOutput(Name: "G4g4r1n", out_Result: new DynamicSchemaColumn + /// { + /// Size = 256, + /// }, ret_Return: 0); + /// + /// db.Execute(@"CREATE OR ALTER PROCEDURE sp_Exp_SomeInputAndOutputWithDataAndReturn + /// @Name nvarchar(50), + /// @Result nvarchar(256) OUTPUT + /// AS + /// SELECT @Result = 'Hi, ' + @Name + ' your lucky number is 42!' + /// + /// SELECT 1 Id, 'Some Name 1' [Name], 'Some Desc 1' [Desc], GETDATE() [Date] + /// UNION ALL SELECT 2 Id, 'Some Name 2', 'Some Desc 2', GETDATE() [Date] + /// + /// RETURN 42;"); + /// var res7 = db.Procedures.sp_Exp_SomeInputAndOutputWithDataAndReturn, sp_Exp_SomeInputAndOutputWithDataAndReturn_Result>(Name: "G4g4r1n", out_Result: new DynamicColumn + /// { + /// Schema = new DynamicSchemaColumn + /// { + /// Size = 256, + /// }, + /// }, ret_Return: 0); + /// var res8 = db.Procedures.sp_Exp_SomeInputAndOutputWithDataAndReturn, sp_Exp_SomeInputAndOutputWithDataAndReturn_Result>(Name: "G4g4r1n", out_Result: new DynamicSchemaColumn + /// { + /// Size = 256, + /// }, ret_Return: 0); + /// } + /// + ///private class sp_Exp_SomeData_Result + ///{ + /// public virtual int Id { get; set; } + /// public virtual string Name { get; set; } + /// public virtual string Desc { get; set; } + /// public virtual DateTime Date { get; set; } + ///} + ///private class sp_Exp_SomeInputAndOutput_Result + ///{ + /// public virtual string Result { get; set; } + /// public virtual string Return { get; set; } + ///} + ///private class sp_Exp_SomeInputAndOutputWithDataAndReturn_Result + ///{ + /// public class Data + /// { + /// public virtual int Id { get; set; } + /// public virtual string Name { get; set; } + /// public virtual string Desc { get; set; } + /// public virtual DateTime Date { get; set; } + /// } + /// public virtual List sp_Exp_SomeInputAndOutputWithDataAndReturn { get; set; } + /// public virtual string Result { get; set; } + /// public virtual string Return { get; set; } + ///} + /// + /// public dynamic Procedures { get @@ -129,7 +213,7 @@ namespace DynamORM if (_proc == null) { if ((Options & DynamicDatabaseOptions.SupportStoredProcedures) != DynamicDatabaseOptions.SupportStoredProcedures) - throw new InvalidOperationException("Database connection desn't support stored procedures."); + throw new InvalidOperationException("Database connection doesn't support stored procedures."); _proc = new DynamicProcedureInvoker(this); } diff --git a/DynamORM/DynamicProcedureInvoker.cs b/DynamORM/DynamicProcedureInvoker.cs index bd0846e..352431a 100644 --- a/DynamORM/DynamicProcedureInvoker.cs +++ b/DynamORM/DynamicProcedureInvoker.cs @@ -29,6 +29,7 @@ using System; using System.Collections; using System.Collections.Generic; +using System.ComponentModel; using System.Data; using System.Dynamic; using System.Linq; @@ -105,6 +106,8 @@ namespace DynamORM #region Prepare arguments int alen = args.Length; + bool retIsAdded = false; + if (alen > 0) { for (int i = 0; i < alen; i++) @@ -119,30 +122,108 @@ namespace DynamORM { var dcv = (DynamicColumn)arg; - string paramName = dcv.Alias ?? dcv.ColumnName ?? + string paramName = i.ToString(); + bool isOut = false; + bool isRet = false; + bool isBoth = false; + + if (info.ArgumentNames.Count > i) + { + isOut = info.ArgumentNames[i].StartsWith("out_"); + isRet = info.ArgumentNames[i].StartsWith("ret_"); + isBoth = info.ArgumentNames[i].StartsWith("both_"); + + paramName = isOut || isRet ? + info.ArgumentNames[i].Substring(4) : + isBoth ? info.ArgumentNames[i].Substring(5) : + info.ArgumentNames[i]; + } + + paramName = dcv.Alias ?? dcv.ColumnName ?? (dcv.Schema.HasValue ? dcv.Schema.Value.Name : null) ?? - (info.ArgumentNames.Count > i ? info.ArgumentNames[i] : i.ToString()); + paramName; - bool isOut = dcv.ParameterDirection == ParameterDirection.Output || - dcv.ParameterDirection == ParameterDirection.ReturnValue; + if (!isOut && !isRet && !isBoth) + { + isOut = dcv.ParameterDirection == ParameterDirection.Output; + isRet = dcv.ParameterDirection == ParameterDirection.ReturnValue; + isBoth = dcv.ParameterDirection == ParameterDirection.InputOutput; + } - if (isOut || dcv.ParameterDirection == ParameterDirection.InputOutput) + if (isRet) + retIsAdded = true; + + if (isOut || isRet || isBoth) { if (retParams == null) retParams = new Dictionary(); retParams.Add(paramName, cmd.Parameters.Count); } - if (dcv.Schema != null) { + if (dcv.Schema != null) + { var ds = dcv.Schema.Value; cmd.AddParameter( - _db.GetParameterName(paramName), dcv.ParameterDirection, + _db.GetParameterName(paramName), + isOut ? ParameterDirection.Output : + isRet ? ParameterDirection.ReturnValue : + isBoth ? ParameterDirection.InputOutput : + ParameterDirection.Input, ds.Type, ds.Size, ds.Precision, ds.Scale, - isOut ? DBNull.Value : dcv.Value); - } else + (isOut || isRet) ? DBNull.Value : dcv.Value); + } + else cmd.AddParameter( - _db.GetParameterName(paramName), dcv.ParameterDirection, - arg == null ? DbType.String : arg.GetType().ToDbType(), 0, isOut ? DBNull.Value : dcv.Value); + _db.GetParameterName(paramName), + isOut ? ParameterDirection.Output : + isRet ? ParameterDirection.ReturnValue : + isBoth ? ParameterDirection.InputOutput : + ParameterDirection.Input, + arg == null ? DbType.String : arg.GetType().ToDbType(), + isRet ? 4 : 0, + (isOut || isRet) ? DBNull.Value : dcv.Value); + } + else if (arg is DynamicSchemaColumn) + { + var dsc = (DynamicSchemaColumn)arg; + + string paramName = i.ToString(); + bool isOut = false; + bool isRet = false; + bool isBoth = false; + + if (info.ArgumentNames.Count > i) + { + isOut = info.ArgumentNames[i].StartsWith("out_"); + isRet = info.ArgumentNames[i].StartsWith("ret_"); + isBoth = info.ArgumentNames[i].StartsWith("both_"); + + paramName = isOut || isRet ? + info.ArgumentNames[i].Substring(4) : + isBoth ? info.ArgumentNames[i].Substring(5) : + info.ArgumentNames[i]; + } + + paramName = dsc.Name ?? paramName; + + if (isRet) + retIsAdded = true; + + if (isOut || isRet || isBoth) + { + if (retParams == null) + retParams = new Dictionary(); + retParams.Add(paramName, cmd.Parameters.Count); + } + + cmd.AddParameter( + _db.GetParameterName(paramName), + isOut ? ParameterDirection.Output : + isRet ? ParameterDirection.ReturnValue : + isBoth ? ParameterDirection.InputOutput : + ParameterDirection.Input, + dsc.Type, dsc.Size, dsc.Precision, dsc.Scale, + DBNull.Value); } else { @@ -152,6 +233,9 @@ namespace DynamORM bool isRet = info.ArgumentNames[i].StartsWith("ret_"); bool isBoth = info.ArgumentNames[i].StartsWith("both_"); + if (isRet) + retIsAdded = true; + string paramName = isOut || isRet ? info.ArgumentNames[i].Substring(4) : isBoth ? info.ArgumentNames[i].Substring(5) : @@ -168,8 +252,11 @@ namespace DynamORM _db.GetParameterName(paramName), isOut ? ParameterDirection.Output : isRet ? ParameterDirection.ReturnValue : - isBoth ? ParameterDirection.InputOutput : ParameterDirection.Input, - arg == null ? DbType.String : arg.GetType().ToDbType(), 0, isOut ? DBNull.Value : arg); + isBoth ? ParameterDirection.InputOutput : + ParameterDirection.Input, + arg == null ? isRet ? DbType.Int32 : DbType.String : arg.GetType().ToDbType(), + isRet ? 4 : 0, + (isOut || isRet) ? DBNull.Value : arg); } else cmd.AddParameter(_db, arg); @@ -220,7 +307,7 @@ namespace DynamORM cache = rdr.CachedReader(); while (cache.Read()) - listInstance.Add(cache[0] == DBNull.Value ? defVal : argType.CastObject(cache[0])); + listInstance.Add(cache[0] != null && cache[0] != DBNull.Value ? argType.CastObject(cache[0]) : defVal); mainResult = listInstance; } @@ -237,7 +324,7 @@ namespace DynamORM while (cache.Read()) { - if (cache[0] == DBNull.Value && Guid.TryParse(cache[0].ToString(), out Guid g)) + if (cache[0] != null && cache[0] != DBNull.Value && Guid.TryParse(cache[0].ToString(), out Guid g)) listInstance.Add(g); } @@ -247,32 +334,41 @@ namespace DynamORM { DynamicTypeMap mapper = DynamicMapperCache.GetMapper(argType); if (mapper == null) - throw new InvalidCastException(string.Format("Don't konw what to do with this type: '{0}'.", argType.ToString())); + throw new InvalidCastException(string.Format("Don't know what to do with this type: '{0}'.", argType.ToString())); IDataReader cache = null; using (IDataReader rdr = cmd.ExecuteReader()) cache = rdr.CachedReader(); - mainResult = cache.EnumerateReader().MapEnumerable(argType).ToList(); + var lt = typeof(List<>); + var ltc = lt.MakeGenericType(argType); + var instance = Activator.CreateInstance(ltc) as IList; + + foreach (var item in cache.EnumerateReader()) + instance.Add(DynamicExtensions.Map(item, argType)); + + mainResult = instance; + + //mainResult = cache.EnumerateReader().MapEnumerable(argType).ToList(); } } else if (types[0].IsValueType || types[0] == typeof(string)) { mainResult = cmd.ExecuteScalar(); - if (mainResult != DBNull.Value) + if (mainResult != null && mainResult != DBNull.Value) mainResult = types[0].CastObject(mainResult); } else if (types[0] == typeof(Guid)) { mainResult = cmd.ExecuteScalar(); - if (mainResult != DBNull.Value && Guid.TryParse(mainResult.ToString(), out Guid g)) + if (mainResult != null && mainResult != DBNull.Value && Guid.TryParse(mainResult.ToString(), out Guid g)) mainResult = g; } else { DynamicTypeMap mapper = DynamicMapperCache.GetMapper(types[0]); if (mapper == null) - throw new InvalidCastException(string.Format("Don't konw what to do with this type: '{0}'.", types[0].ToString())); + throw new InvalidCastException(string.Format("Don't know what to do with this type: '{0}'.", types[0].ToString())); using (IDataReader rdr = cmd.ExecuteReader()) if (rdr.Read()) @@ -282,8 +378,33 @@ namespace DynamORM } } else + { + var returnName = _db.GetParameterName("___result___"); + if (!retIsAdded) + cmd.AddParameter(returnName, ParameterDirection.ReturnValue, DbType.Int32, 4, 0, 0, DBNull.Value); + mainResult = cmd.ExecuteNonQuery(); + IDbDataParameter returnParam = null; + if (!retIsAdded) + returnParam = cmd.Parameters[returnName] as IDbDataParameter; + else + { + foreach (var e in cmd.Parameters) + { + var p = e as IDbDataParameter; + if (p != null && p.Direction == ParameterDirection.ReturnValue) + { + returnParam = p; + break; + } + } + } + + if (returnParam != null && returnParam.Value != null && returnParam.Value != DBNull.Value) + mainResult = returnParam.Value; + } + #endregion Get main result #region Handle out params diff --git a/Tester/Program.cs b/Tester/Program.cs index f088ff5..8e82ebb 100644 --- a/Tester/Program.cs +++ b/Tester/Program.cs @@ -12,9 +12,7 @@ namespace Tester private static DynamicDatabase GetORM() { return new DynamicDatabase(System.Data.SqlClient.SqlClientFactory.Instance, - "packet size=4096;User Id=sa;Password=sa123;data source=127.0.0.1,1435;initial catalog=MOM_LANGOWSKI_WMS_TEST;", - //"packet size=4096;User Id=sa;Password=sa123;data source=192.168.1.9,1433;initial catalog=MOM_NEXT_Florentyna_WMS_PROD;", - //"packet size=4096;User Id=sa;Password=sa123;data source=127.0.0.1;initial catalog=DynamORM;", + "packet size=4096;User Id=sa;Password=;data source=192.168.22.;initial catalog=PLAYGROUND;", DynamicDatabaseOptions.SingleConnection | DynamicDatabaseOptions.SingleTransaction | DynamicDatabaseOptions.SupportSchema | DynamicDatabaseOptions.SupportStoredProcedures | DynamicDatabaseOptions.SupportTop | DynamicDatabaseOptions.DumpCommands); @@ -31,6 +29,58 @@ namespace Tester using (var db = GetORM()) { + db.Execute(@"CREATE OR ALTER PROCEDURE sp_Exp_Scalar AS SELECT 42;"); + var res0 = db.Procedures.sp_Exp_Scalar(); + var res1 = db.Procedures.sp_Exp_Scalar(); + + db.Execute(@"CREATE OR ALTER PROCEDURE sp_Exp_ReturnInt AS RETURN 42;"); + var res2 = db.Procedures.sp_Exp_ReturnInt(); + + db.Execute(@"CREATE OR ALTER PROCEDURE sp_Exp_SomeData AS +SELECT 1 Id, 'Some Name 1' [Name], 'Some Desc 1' [Desc], GETDATE() [Date] +UNION ALL SELECT 2 Id, 'Some Name 2', 'Some Desc 2', GETDATE() [Date];"); + var res3 = db.Procedures.sp_Exp_SomeData(); + var res4 = db.Procedures.sp_Exp_SomeData>(); + + db.Execute(@"CREATE OR ALTER PROCEDURE sp_Exp_SomeInputAndOutput + @Name nvarchar(50), + @Result nvarchar(256) OUTPUT +AS +SELECT @Result = 'Hi, ' + @Name + ' your lucky number is 42!';"); + var res5 = db.Procedures.sp_Exp_SomeInputAndOutput(Name: "G4g4r1n", out_Result: new DynamicColumn + { + Schema = new DynamicSchemaColumn + { + Size = 256, + }, + }, ret_Return: 0); + var res6 = db.Procedures.sp_Exp_SomeInputAndOutput(Name: "G4g4r1n", out_Result: new DynamicSchemaColumn + { + Size = 256, + }, ret_Return: 0); + + db.Execute(@"CREATE OR ALTER PROCEDURE sp_Exp_SomeInputAndOutputWithDataAndReturn + @Name nvarchar(50), + @Result nvarchar(256) OUTPUT +AS +SELECT @Result = 'Hi, ' + @Name + ' your lucky number is 42!' + +SELECT 1 Id, 'Some Name 1' [Name], 'Some Desc 1' [Desc], GETDATE() [Date] +UNION ALL SELECT 2 Id, 'Some Name 2', 'Some Desc 2', GETDATE() [Date] + +RETURN 42;"); + var res7 = db.Procedures.sp_Exp_SomeInputAndOutputWithDataAndReturn, sp_Exp_SomeInputAndOutputWithDataAndReturn_Result>(Name: "G4g4r1n", out_Result: new DynamicColumn + { + Schema = new DynamicSchemaColumn + { + Size = 256, + }, + }, ret_Return: 0); + var res8 = db.Procedures.sp_Exp_SomeInputAndOutputWithDataAndReturn, sp_Exp_SomeInputAndOutputWithDataAndReturn_Result>(Name: "G4g4r1n", out_Result: new DynamicSchemaColumn + { + Size = 256, + }, ret_Return: 0); + //try //{ // db.Execute("DROP TABLE Experiments "); @@ -50,28 +100,50 @@ namespace Tester //db.Execute("DROP TABLE Experiments "); - IDataReader rdr = db.Procedures.sp_getdate(); - var dt = rdr.ToDataTable(); - var dt2 = db.Procedures.sp_getdate(); + //IDataReader rdr = db.Procedures.sp_getdate(); + //var dt = rdr.ToDataTable(); + //var dt2 = db.Procedures.sp_getdate(); - db.Procedures.usp_API_Generate_Doc_Number(key: Guid.NewGuid(), mdn_id: "ZZ"); + //db.Procedures.usp_API_Generate_Doc_Number(key: Guid.NewGuid(), mdn_id: "ZZ"); - var resL = (db.Procedures.GetProductDesc>() as IEnumerable) - .Cast() - .ToArray(); - var res = db.Procedures.GetProductDesc_withparameters(PID: 707); - res = db.Procedures.GetProductDesc_withDefaultparameters(); + //var resL = (db.Procedures.GetProductDesc>() as IEnumerable) + // .Cast() + // .ToArray(); + //var res = db.Procedures.GetProductDesc_withparameters(PID: 707); + //res = db.Procedures.GetProductDesc_withDefaultparameters(); - int id = -1; - var resD = db.Procedures.ins_NewEmp_with_outputparamaters(Ename: "Test2", out_EId: id); + //int id = -1; + //var resD = db.Procedures.ins_NewEmp_with_outputparamaters(Ename: "Test2", out_EId: id); } } - private class GetProductDesc_Result + private class sp_Exp_SomeData_Result { - public virtual int ProductID { get; set; } - public virtual string ProductName { get; set; } - public virtual string ProductDescription { get; set; } + public virtual int Id { get; set; } + public virtual string Name { get; set; } + public virtual string Desc { get; set; } + public virtual DateTime Date { get; set; } + } + + private class sp_Exp_SomeInputAndOutput_Result + { + public virtual string Result { get; set; } + public virtual string Return { get; set; } + } + + private class sp_Exp_SomeInputAndOutputWithDataAndReturn_Result + { + public class Data + { + public virtual int Id { get; set; } + public virtual string Name { get; set; } + public virtual string Desc { get; set; } + public virtual DateTime Date { get; set; } + } + + public virtual List sp_Exp_SomeInputAndOutputWithDataAndReturn { get; set; } + public virtual string Result { get; set; } + public virtual string Return { get; set; } } } } \ No newline at end of file diff --git a/Tester/Tester.csproj b/Tester/Tester.csproj index adc9048..a3a687c 100644 --- a/Tester/Tester.csproj +++ b/Tester/Tester.csproj @@ -17,7 +17,7 @@ - +