diff --git a/Dapper/DynamicParameters.cs b/Dapper/DynamicParameters.cs index 2569a9383..369987f53 100644 --- a/Dapper/DynamicParameters.cs +++ b/Dapper/DynamicParameters.cs @@ -329,6 +329,39 @@ public T Get(string name) return (T)val; } + /// + /// Param names from templates + /// + public IEnumerable TemplateParameterNames => templates.Select(t => t.GetType().GetProperties().Select(p => p.Name)).SelectMany(p => p); + + /// + /// Get the value of a parameter that was created from a template + /// + /// The type of a parameter + /// + /// The value of the parameter + /// When templates is null or the param wasn't found + public T GetTemplateParameter(string name) + { + if (templates == null) + throw new Exception("There are no templates"); + + foreach (object t in templates) + { + var property = t.GetType().GetProperties().Where(p => p.Name == name).FirstOrDefault(); + + if (property != null) + return (T)property.GetValue(t); + } + + throw new Exception($"Parameter name {name} not present in templates"); + } + + /// + /// Param names from templates and bag + /// + public IEnumerable AllParameterNames => ParameterNames.Concat(TemplateParameterNames); + /// /// Allows you to automatically populate a target property/field from output parameters. It actually /// creates an InputOutput parameter, so you can still pass data in. diff --git a/tests/Dapper.Tests/ParameterTests.cs b/tests/Dapper.Tests/ParameterTests.cs index 7179563ad..41733d4e2 100644 --- a/tests/Dapper.Tests/ParameterTests.cs +++ b/tests/Dapper.Tests/ParameterTests.cs @@ -1593,5 +1593,29 @@ private static int GetExpectedListExpansionCount(int count, bool enabled) if (delta != 0) blocks++; return blocks * padFactor; } + + [Fact] + public void TestGetParameterFromAnonymousType() + { + // https://github.com/DapperLib/Dapper/issues/343 + // https://github.com/DapperLib/Dapper/issues/1113 + + var parameters = new DynamicParameters(new { par = 1 }); + + Assert.Equal(1, parameters.GetTemplateParameter("par")); + Assert.Equal("par", parameters.TemplateParameterNames.First()); + } + + [Fact] + public void TestGetAllParemeters() + { + var parameters = new DynamicParameters(new { par1 = 1 }); + parameters.Add("par2", 2); + + var paramNames = parameters.AllParameterNames.ToList(); + + Assert.Equal("par2", paramNames[0]); + Assert.Equal("par1", paramNames[1]); + } } }