mirror of
https://github.com/DapperLib/Dapper.git
synced 2026-10-17 05:12:13 +08:00
aecffecae1
* attempt NRT makeover - annotate NRTs on GridReader API - add protected access to some of the GridReader internals - switch GridReader callbacks to be more type-independent docs lib updates; deal with yellow warnings and test failures (SQL server certs and cancellation surfacing differently) fix break simplify proposed GridReader changes to protected OnBeforeGrid and OnAfterGrid[Async] Builds: Bump library versions (#1935) Tests: Upgrade dependencies for Dependabot (#1936) I'll do a pass at all of these later, but getting CVE versions out of the pipe. Resolving 4 alerts here: https://github.com/DapperLib/Dapper/security/dependabot merge and lib updates allow Identity to be constructed on-the-fly inside GridReader fix build warnings include readme rev minor - enable [SkipLocalsInit] everywhere - use NET5_0_OR_GREATER for remoting check # Conflicts: # Dapper/CommandDefinition.cs # Dapper/DefaultTypeMap.cs # Dapper/SqlMapper.Async.cs # Dapper/SqlMapper.IDataReader.cs # Dapper/SqlMapper.Link.cs # Dapper/SqlMapper.cs # Directory.Build.props * shipped, not unshipped * fixup SqlBuilder; use is null / is not null * use central package management (#1949) * Nullable test tweaks * Nuget: let's just remove it! * 2 test fixes from review * fix FindExplicitConstructor * add GetPropertySetterOrThrow * fix NRT on FindConstructor * DapperRow: value is object? * use NotNullWhen * make constructor problem more obvious * test fixes --------- Co-authored-by: Nick Craver <nrcraver@gmail.com>
65 lines
2.3 KiB
C#
65 lines
2.3 KiB
C#
using System;
|
|
using System.Collections.Concurrent;
|
|
using System.Data.Common;
|
|
using System.Linq.Expressions;
|
|
using System.Reflection;
|
|
|
|
namespace Dapper.ProviderTools
|
|
{
|
|
/// <summary>
|
|
/// Helper utilities for working with database exceptions
|
|
/// </summary>
|
|
public static class DbExceptionExtensions
|
|
{
|
|
/// <summary>
|
|
/// Indicates whether the provided exception has an integer Number property with the supplied value
|
|
/// </summary>
|
|
public static bool IsNumber(this DbException exception, int number)
|
|
=> exception is not null && ByTypeHelpers.Get(exception.GetType()).IsNumber(exception, number);
|
|
|
|
|
|
private sealed class ByTypeHelpers
|
|
{
|
|
private static readonly ConcurrentDictionary<Type, ByTypeHelpers> s_byType
|
|
= new ConcurrentDictionary<Type, ByTypeHelpers>();
|
|
private readonly Func<DbException, int>? _getNumber;
|
|
|
|
public bool IsNumber(DbException exception, int number)
|
|
=> _getNumber is not null && _getNumber(exception) == number;
|
|
|
|
public static ByTypeHelpers Get(Type type)
|
|
{
|
|
if (!s_byType.TryGetValue(type, out var value))
|
|
{
|
|
s_byType[type] = value = new ByTypeHelpers(type);
|
|
}
|
|
return value;
|
|
}
|
|
|
|
private ByTypeHelpers(Type type)
|
|
{
|
|
_getNumber = TryGetInstanceProperty<int>("Number", type);
|
|
}
|
|
|
|
private static Func<DbException, T>? TryGetInstanceProperty<T>(string name, Type type)
|
|
{
|
|
try
|
|
{
|
|
var prop = type.GetProperty(name, BindingFlags.Public | BindingFlags.Instance);
|
|
if (prop is null || !prop.CanRead) return null;
|
|
if (prop.PropertyType != typeof(T)) return null;
|
|
|
|
var p = Expression.Parameter(typeof(DbException), "exception");
|
|
var body = Expression.Property(Expression.Convert(p, type), prop);
|
|
var lambda = Expression.Lambda<Func<DbException, T>>(body, p);
|
|
return lambda.Compile();
|
|
}
|
|
catch
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|