mercredi 23 janvier 2019

How to cast an object from Npgsqlreader to specific property type?

I'm trying to write a generic method for casting received data from Npgsqlreader to a specific C# object (.NET Core 2.1).

For better performance in reflection, I've decided to use a FastMember package.

Here's some code:

using System;
using System.Linq;

using FastMember;

using Npgsql;

namespace API.Helpers {
    public static class Mapper {
        public static T MapToObject<T>(this NpgsqlDataReader reader) where T : class, new() {
            var accessor = TypeAccessor.Create(typeof(T));
            var members = accessor.GetMembers();
            var t = new T();

            for (int i = 0; i < reader.FieldCount; i++) {
                if (!reader.IsDBNull(i)) {
                    string fieldName = reader.GetName(i);

                    if (members.Any(m => string.Equals(m.Name, fieldName, StringComparison.OrdinalIgnoreCase))) {
                        accessor[t, fieldName] = reader.GetValue(i);
                    }
                }

            }

            return t;
        }
    }
}

For example, I've got this model for casting:

public class ThreadModel {
    public long? id { get; set; }
    public string author { get; set; }
    public System.DateTime? created { get; set; }
    public string forum { get; set; }
    public string message { get; set; }
    public string slug { get; set; }
    public string title { get; set; }
    public long votes { get; set; }
}

But in some cases the method gives me an exception like: Unable to cast object of type 'System.Int32' to type 'System.Int64' which confused me.

So, I've decided to cast value to a type of a specific property like this:

foreach (var m in members) {
    if (string.Equals(m.Name, fieldName, StringComparison.OrdinalIgnoreCase)) {
        var fieldType = m.Type;
        accessor[t, fieldName] = reader.GetValue(i) as fieldType;
    }
}

But I'm unable to do it: fieldType is a variable, but is used like a type.

Is this even possible to do what I want? Or there are some other ways for casting?





Aucun commentaire:

Enregistrer un commentaire