1

I built a VB.NET code to sort several type like string,number ... Now I try to Had date.

If (TypeClass.GetProperties().Any(Function(prop) prop.Name = sortPropertyName AndAlso prop.CanRead)) Then

    'Information sur la propriété recherchée
    Dim pinfo As PropertyInfo = TypeClass.GetProperty(sortPropertyName)
    Dim Typ = pinfo.PropertyType.Name
    Dim toStr As Expression

    Dim Expr As Expression = Expression.Property(paramExpr, pinfo)

    toStr = Expression.Call(If(pinfo.PropertyType.IsValueType, Expr, Expression.Coalesce(Expr, Expression.Constant(String.Empty))), "ToString", Nothing)


    Dim orderByFunc As Func(Of MaClass, Object) = Expression.Lambda(Of Func(Of MaClass, Object))(toStr, paramExpr).Compile()
    Dim sortFunc As Func(Of IEnumerable(Of MaClass), IOrderedEnumerable(Of MaClass)) = Nothing

    If (Not CBool(Sort.Sens)) Then
        sortFunc = (Function(source) source.OrderBy(orderByFunc))
    Else
        sortFunc = (Function(source) source.OrderByDescending(orderByFunc))
    End If

    query = sortFunc(query).ToList()
End If

The problem is when I sort it's not sort Date but a string like

31/12/2005; 31/11/2011; 31/10/2007 ...

When I Sort it's better to find

31/11/2011; 31/10/2007; 31/12/2005

Then I try this modify

 If Typ.Contains("DateTime") Then 'Add For DateTime here
     toStr = Expression.Call(If(pinfo.PropertyType.IsValueType, Expr, Expression.Coalesce(Expr, Expression.Constant(Date.MinValue))), "ToString", Nothing)
Else
    toStr = Expression.Call(If(pinfo.PropertyType.IsValueType, Expr, Expression.Coalesce(Expr, Expression.Constant(String.Empty))), "ToString", Nothing)
End If

but i don't know how replace 'ToString'

I try

toStr = Expression.Call(If(pinfo.PropertyType.IsValueType, Expr, Expression.Coalesce(Expr, Expression.Constant(Date.MinValue))), "ToString(""yyyy MM dd"")", Nothing)

But I was following error

ex = {"Aucune méthode 'ToString("yyyy MM dd")' n'existe sur le type 'System.Nullable`1[System.DateTime]'."}

Translate by Google

"No method 'ToString (" yyyy dd MM ")' exists on the type 'System.Nullable`1 [System.DateTime]'.

I try too Ticks, Date or Year,,Value.Ticks, GetValueOrDefault.Year.ToString but same error

Perhaps there is a better way

Thnks for your help

Servy
  • 202,030
  • 26
  • 332
  • 449
YannickIngenierie
  • 602
  • 1
  • 13
  • 37

1 Answers1

1
  1. .Contains("DateTime") will match both Nullable<DateTime> and DateTime types, the error your seeing is because you're trying to call obj.Value.ToString("yyyy MM dd") what you've written isn't a ToString overload on the nullable object (which just calls it's contained ToString method) it's an overload on the contained DateTime object
  2. There is a boolean on the reflection objects that will tell you if your looking at the actual type or a Generic object (like Nullable<>)
  3. This is also why you can't find the Ticks property, as it only exists on the child DateTime object. In your normal code Nullable<> objects are implicitly cast to their contained type (automatically navigating to the Value object)
  4. looking at msdn, you pass in arguments as the 4th parameter in C# as opposed to setting them in the string, VB is likely identical
  5. I don't think you can navigate to the Value object using the string parameter by calling "Value.Ticks" as firstly "Ticks" isn't a method it's a property and secondly .Net won't be able to translate the string into a methodInfo object from the Nullable<T> type - because it doesn't exist.

You should navigate to the "Value" object or cast to the underlying object type as part of the Expr expression by detecting if it's a generic Nullable<T> type

Dead.Rabit
  • 1,965
  • 1
  • 28
  • 46
  • I'm not sur to understand. Can you help me to correct my code – YannickIngenierie Feb 03 '15 at 15:38
  • Nope, I don't do VB I'm afraid, hopefully all the information you need is in there.. as I see it, it's just a matter of deciding where you want to unwrap these nullable objects. This might be a little tricky as it seems the answer to your earlier question (http://stackoverflow.com/questions/27720165/expression-lambda-to-order-fields-with-null-value) requires that the nullable objects are in place. – Dead.Rabit Feb 03 '15 at 15:47
  • It looks as though you can call extension methods using Expression.Call (http://stackoverflow.com/questions/8337774/lambda-and-expression-call-for-an-extension-method) which may be another option for you. By extending `Nullable` you could write a method to retrieve the desired date string or a ticks value from the contained DateTime and call it directly from the `Nullable` object. I'm sure this probably isn't the best approach though. – Dead.Rabit Feb 03 '15 at 15:48
  • @Dead.Rabbit I replace with 'toStr = Expression.Call(If(pinfo.PropertyType.IsValueType, Expr, Expression.Coalesce(Expr, Expression.Constant(Date.MinValue))), "ToString", Nothing, Expression.Constant("yyyy MM dd"))' but now error is **No method 'ToString' on type 'System.Nullable`1 [System.DateTime] is not consistent with the arguments provided** – YannickIngenierie Feb 03 '15 at 15:51
  • Just to give the right response : toStr = Expression.Call(Expr, "ToString", Nothing, Expression.Constant("yyyy MM dd")) – YannickIngenierie Feb 04 '15 at 10:16
  • I forget to say I used field type Date? but it was no using cause you can put nothing in Type Date directly. – YannickIngenierie Feb 04 '15 at 10:48