NPoco
NPoco copied to clipboard
Custom Mapper works but NPoco despite this throws
"NPoco.SqlServer" Version="5.1.2"
I have custom mapper for complex object. Mapper serializes object to JSON and vice-versa. Mapper works (serialization and deserialization returns proper values from/to db).
Exception is odd:
NullReferenceException: Object reference not set to an instance of an object.
NPoco.RowMappers.PropertyMapper.MapValue(GroupResult<PosName> posName, object[] values, Func<object, object> converter, object instance, PocoColumn pocoColumn, object defaultValue)
NPoco.RowMappers.PropertyMapper+<>c__DisplayClass8_2.<BuildMapPlans>b__3(DbDataReader reader, object[] values, object instance)
NPoco.RowMappers.PropertyMapper+<>c__DisplayClass7_0.<BuildMapPlan>b__1(DbDataReader reader, object[] values, object instance)
NPoco.RowMappers.PropertyMapper.Map(DbDataReader dataReader, RowMapperContext context)
NPoco.MappingFactory.Map(DbDataReader dataReader, object instance)
NPoco.Database.ReadAsync<T>(object instance, DbDataReader r, PocoData pd)
NPoco.Database.ReadAsync<T>(object instance, DbDataReader r, PocoData pd)
NPoco.Database.QueryAsync<T>(T instance, Expression<Func<T, IList>> listExpression, Func<T, object[]> idFunc, Sql Sql, PocoData pocoData)
NPoco.Database.QueryAsync<T>(T instance, Expression<Func<T, IList>> listExpression, Func<T, object[]> idFunc, Sql Sql, PocoData pocoData)
NPoco.Database.QueryAsync<T>(T instance, Expression<Func<T, IList>> listExpression, Func<T, object[]> idFunc, Sql Sql, PocoData pocoData)
System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable<TResult>+ConfiguredValueTaskAwaiter.GetResult()
System.Linq.AsyncEnumerable.<SingleOrDefaultAsync>g__Core|534_0<TSource>(IAsyncEnumerable<TSource> source, CancellationToken cancellationToken) in SingleOrDefault.cs
System.Linq.AsyncEnumerable.<SingleOrDefaultAsync>g__Core|534_0<TSource>(IAsyncEnumerable<TSource> source, CancellationToken cancellationToken) in SingleOrDefault.cs
Mapper:
public class ReferenceCollectionMapper : DefaultMapper
{
private readonly IColumnSerializer _serializer = DatabaseFactory.ColumnSerializer;
public override Func<object, object> GetFromDbConverter(Type destType, Type sourceType)
{
var isReferenceCollection = IsReferenceCollection(destType);
return isReferenceCollection
? o => o == null ? null : _serializer.Deserialize((string)o, typeof(ReferenceCollection))
: base.GetFromDbConverter(destType, sourceType);
}
public override Func<object, object> GetToDbConverter(Type destType, MemberInfo sourceMemberInfo)
{
var sourceType = sourceMemberInfo.GetMemberInfoType();
return IsReferenceCollection(sourceType)
? o => o == null ? null : _serializer.Serialize(o)
: base.GetToDbConverter(destType, sourceType);
}
private static bool IsReferenceCollection(Type type) => type == typeof(ReferenceCollection);
}
One more thing. Method GetFromDbConverter(MemberInfo destMemberInfo, Type sourceType)
is never invoked for member type ReferenceCollection
. 😞
It turns out that for simple clr types like int, int[], List<int>
works but doesn't work when it is custom object type, for eg.: ReferenceCollection.
public class ReferenceCollection
{
public List<Item> Items { get; private init; } = new();
public class Item
{
public int Id { get; private init; }
public string Name { get; private init; }
public static Item Create(int id, string name)
{
return new()
{
Id = id,
Name = name
};
}
}
}