Skip to content

Commit

Permalink
#753 #761 - Added a descriptive message for the unmatched ctor argume…
Browse files Browse the repository at this point in the history
…nts during the hydration process.
  • Loading branch information
mikependon committed Feb 6, 2021
1 parent 7b1fc25 commit d1c088f
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 3 deletions.
10 changes: 8 additions & 2 deletions RepoDb.Core/RepoDb/Reflection/Compiler/Compiler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -107,13 +107,18 @@ internal struct FieldDirection
/// <summary>
/// A class that contains both the property <see cref="MemberAssignment"/> object and the constructor argument <see cref="Expression"/> value.
/// </summary>
internal struct MemberBinding
internal class MemberBinding
{
/// <summary>
/// Gets the instance of <see cref="ClassProperty"/> object in used.
/// </summary>
public ClassProperty ClassProperty { get; set; }

/// <summary>
/// Gets the instance of <see cref="ParameterInfo"/> object in used.
/// </summary>
public ParameterInfo ParameterInfo { get; set; }

/// <summary>
/// Gets the current member assignment of the defined property.
/// </summary>
Expand All @@ -129,7 +134,7 @@ internal struct MemberBinding
/// </summary>
/// <returns>The presented string.</returns>
public override string ToString() =>
ClassProperty.ToString();
ClassProperty?.ToString() ?? ParameterInfo?.ToString();
}

#endregion
Expand Down Expand Up @@ -1275,6 +1280,7 @@ internal static IEnumerable<MemberBinding> GetMemberBindingsForDataEntity<TResul
memberBindings.Add(new MemberBinding
{
ClassProperty = classPropertyParameterInfo.ClassProperty,
ParameterInfo = classPropertyParameterInfo?.ParameterInfo,
MemberAssignment = memberAssignment,
Argument = argument
});
Expand Down
19 changes: 18 additions & 1 deletion RepoDb.Core/RepoDb/Reflection/Compiler/DataReaderToType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,13 +94,30 @@ internal static Func<DbDataReader, TResult> CompileDataReaderToDataEntity<TResul
// Throw an error if there are no bindings
if (arguments?.Any() != true && memberAssignments?.Any() != true)
{
throw new InvalidOperationException($"There are no 'constructor parameter' and/or 'property member' bindings found between the ResultSet of the data reader and the type '{typeOfResult.FullName}'.");
throw new InvalidOperationException($"There are no 'constructor parameter' and/or 'property member' bindings found between the resultset of the data reader and the type '{typeOfResult.FullName}'. " +
$"Make sure the 'constructor arguments' and/or 'model properties' are matching the list of the fields returned by the data reader object.");
}

// Initialize the members
var constructorInfo = typeOfResult.GetConstructorWithMostArguments();
var entityExpression = (Expression)null;

// Validate arguments equality
if (arguments?.Any() == true)
{
var parameters = constructorInfo.GetParameters();
var unmatches = parameters
.Where(e => memberBindings.FirstOrDefault(binding => binding.Argument != null &&
string.Equals(binding.ParameterInfo?.Name, e.Name, StringComparison.OrdinalIgnoreCase)) == null);

// Throw the detailed message
if (unmatches?.Any() == true)
{
var unmatchesNames = unmatches.Select(e => e.Name).Join(",");
throw new MissingMemberException($"The following ctor arguments ('{unmatchesNames}') for type '{typeOfResult.FullName}' are not matching from any of the resultset fields returned by the data reader object.");
}
}

try
{
// Constructor arguments
Expand Down

0 comments on commit d1c088f

Please sign in to comment.