2017-09-08 4 views
0

Fondamentalement, j'ai besoin d'un convertisseur qui convertit un objet DataReader en type générique.Comment affecter des valeurs nulles au type de propriété dynamique

quand je fais -

while(dataReader.HasRows()){ 
    var result= dataReader.ConvertToObject<MyModel>(); 
} 

Il appelle une méthode d'extension de type générique -

public static T ConvertToObject<T>(this DbDataReader reader) where T : new() 
{ 
    T res = new T(); 

    T t = new T(); 

    for (int inc = 0; inc < reader.FieldCount; inc++) 
    { 
     Type type = t.GetType(); 
     PropertyInfo prop = type.GetProperty(reader.GetName(inc)); 
     var value = reader.GetValue(inc); 
     if (value == System.DBNull.Value) 
     { 
      value = null; 
     } 

     var targetType = IsNullableType(prop.PropertyType) ? Nullable.GetUnderlyingType(prop.PropertyType) : prop.PropertyType; 

     value = Convert.ChangeType(value, targetType); 

     prop.SetValue(t, value, null); 
    } 

    res = t; 
    return res; 
} 

private static bool IsNullableType(Type type) 
{ 
    return type.IsConstructedGenericType && type.GetGenericTypeDefinition().Equals(typeof(Nullable<>)); 
} 

Il fonctionne très bien jusqu'à ce que le résultat dans datareader est System.DBNull sauf le System.String

Pour gérer les valeurs nulles, j'ai vérifié avec force si la valeur est de type System.DBNull puis assignez-lui un C# NULL objet.

if (value == System.DBNull.Value) 
{ 
    value = null; 
} 

Ceci échoue cependant la conversion lorsque le résultat est nul pour un objet de type numérique.

Donc, fondamentalement, je suis en train de faire est lorsque la valeur de résultat est le type - System.Nullable[System.Decimal]

puis

if (value == System.DBNull.Value) 
{ 
    value = (System.Decimal?) null; 
} 

Ou

value = (System.DateTime?)null //for DateTime 
value = (System.Int32?)null //for Int32 

Ce que j'ai essayé d'obtenir la propriété dynamique tapez

if (value == System.DBNull.Value) 
{ 
    value = (prop.PropertyType ?) null; // to get it dynamic 
} 

Cela n'a pas fonctionné. S'il vous plaît laissez-moi savoir ce que je dois faire?

+4

Avez-vous essayé d'utiliser 'default (T)'? –

+0

Avez-vous envisagé d'utiliser un micro-ORM comme PetaPoco? – mjwills

+0

@JonSkeet, Pas encore. Laissez-moi essayer – Manoj

Répondre

1

Vous ne pouvez pas spécifier null comme valeur de type T car il se peut que cette valeur ne soit pas valide pour T. (Pensez int etc.)

Cependant, vous pouvez utiliser default(T), qui sera la valeur par défaut pour T - la même valeur que vous obtiendriez si vous avez laissé un champ de type T non initialisée, par exemple. Ce sera:

  • Pour les types de référence, une valeur NULL littérale
  • Pour les types de valeur nullables, la valeur nulle du type
  • Pour les types de valeur non nulle, le "tout à zéro" la valeur (0 pour toutes les valeurs numériques etc.)