3

私の ASP.Net MVC ページでは、列ヘッダーをクリックしてその列で並べ替えることができますが、これには aspx の "マジック ストリング" が含まれており、実行時に問題が発生する可能性があります。sort by に渡された値が有効かどうかを実行時に確認しようとしています。すべてのエンティティが継承する基本クラスがあります。

Public MustInherit Class BaseEntity(Of T)
'Some Property and method definitions...'

    Public Shared Function IsValidSearchProperty(name As String) As Boolean
        Dim rootPart As String = name
        Dim nested As Boolean = False
        If rootPart.Contains(".") Then
            rootPart = rootPart.Split("."c)(0)
            nested = True
        End If
        Dim properties As PropertyInfo() = GetType(T).GetProperties()
        For Each prop As PropertyInfo In properties
            If prop.Name = rootPart Then
                If nested Then
                    'This is where my issue is'
                    Return Convert.ToBoolean(
                    prop.PropertyType.InvokeMember("IsValidSearchProperty",
                                                   BindingFlags.InvokeMethod Or BindingFlags.Public Or BindingFlags.Static Or BindingFlags.FlattenHierarchy,
                                                   Nothing, Nothing, New Object() {name.Substring(name.IndexOf(".") + 1)})
                                            )
                Else
                    Return True
                End If
            End If
        Next
        Return False
    End Function
End Class

クラス階層の深さが 1 層を超える入れ子になったプロパティを検証しようとしている場合を除き、これはうまく機能します。例えば:

'Pseudocode Hierarchy
BaseEntity(of T)
    PersonEntity : Inherits BaseEntity(Of PersonEntity)
        Property FirstName as string
    PatientEntity : Inherits PersonEntity
        Property PatientType as int
    VisitEntity : Inherits BaseEntity(Of VisitEntity)
        Property Patient as PatientEntity

Patient.FirstName による訪問の並べ替えは正常に機能し、プロパティは再帰的に検出されますが、Patient.PatientType に基づいて訪問を並べ替えようとすると、PatientType プロパティが見つかりません。IsValidSearchProperty は最初に VisitEntity から呼び出され、Patient プロパティを検索し、PatientEntity 型として表示されますが、このメソッドが InvokeMember を使用して自分自身を再帰的に呼び出す場合 (これは、プロパティ Type を使用してそれを呼び出そうとする方法です) 、2 番目の呼び出しでは、GetType(T) はタイプ PersonEntity であり、PatientType を持っていません。これを行う方法に関する提案は、ネストされた呼び出しの Type を正しく解決しますか?

このメソッドは次のように呼び出されます。

VisitEntity.IsValidSearchProperty("Patient.FirstName") 
VisitEntity.IsValidSearchProperty("Patient.PatientType")  '* This one doesn't work
PatientEntity.IsValidSearchProperty("PatientType")
PatientEntity.IsValidSearchProperty("FirstName")

アップデート

私がこれをどのように使用しているかについての詳細は次のとおりです。

                Dim sorts() As String = SortExpression.Split(";")

                For Each sort As String In sorts
                    Dim sortParts() As String = sort.Split(" ")

                    If VisitEntity.IsValidSearchProperty(sortParts(0)) Then
                        If sortParts(1).ToLower = "true" Then
                            visits = visits.OrderBy(Of VisitEntity)(sortParts(0).ToString(), SortDirection.Ascending)
                        Else
                            visits = visits.OrderBy(Of VisitEntity)(sortParts(0).ToString(), SortDirection.Descending)
                        End If
                    Else
                        _log.WarnFormat("Found invalid sort property {0}", sortParts(0))
                    End If
                Next

SortExpression は、「Patient.PatientType True;Patient.FirstName True」のようなものになります。

4

2 に答える 2

2

InvokeMember現在の型ではなく基本型を呼び出す理由がわかりません。ただし、その動作を回避するために関数を変更します。以下では、チェックする型をパラメーターとして受け取る関数のプライベート オーバーロードを使用しています。関数がドリルダウンすると、このオーバーロードを呼び出して、チェックしたい型を渡すことができます。これにより、メソッドが呼び出されるクラスとGetType(T)、そのクラスに対して返される値の問題が解消されます。

Public Shared Function IsValidSearchProperty(name As String) As Boolean
    Dim CurrentType = GetType(T).GetProperties()
    Return IsValidSearchProperty(name, CurrentType)
End Function 

Private Shared Function IsValidSearchProperty(name As String, CurrentType as Type) As Boolean
    Dim rootPart As String = name
    Dim nested As Boolean = False
    If rootPart.Contains(".") Then
        rootPart = rootPart.Split("."c)(0)
        nested = True
    End If
    Dim properties As PropertyInfo() = CurrentType.GetProperties()
    For Each prop As PropertyInfo In properties
        If prop.Name = rootPart Then
            If nested Then
                'This is where my issue is'
                Return IsValidSearchProperty(name.Substring(name.IndexOf(".") + 1), prop.PropertyType)

            Else
                Return True
            End If
        End If
    Next
    Return False
End Function
于 2012-12-03T17:34:32.467 に答える
1

私は自分で遊んでみましたが、これがあなたの問題ではないかと思います...

Sub Main
    PersonEntity.IsValidSearchProperty()
    PatientEntity.IsValidSearchProperty()
End Sub

' Define other methods and classes here

public class BaseEntity(of T)

    public shared sub IsValidSearchProperty ()
        Console.Write(GetType(T))
    end sub

end class

public class PersonEntity
    inherits BaseEntity(of PersonEntity)

end class

public class PatientEntity
    inherits PersonEntity

end class

これは、あなたの継承がどのように機能していると私が考えるかの簡単な例です。BaseEntity を構築するときに渡される汎用パラメーターが問題のエンティティであると想定しました。PersonEntity は、一般的なパラメーターを持つ別の抽象ではなく、具体的であると想定しています。

私がリストしたコードの問題は、PatientEntity を呼び出すときIsValidSearchPropertyに、型パラメーター TPersonEntityがまだ PersonEntity クラスから継承されていることです。

これはあなたのクラスと同じかもしれないし、そうでないかもしれませんが、あなたの GetType が PatientEntity の代わりに PersonEntity を返す場合、これがあなたの問題である可能性があります。

これらのクラスのインスタンスでソートしようとしている場合、インスタンスがあり、これをインスタンスメソッドに変換できると思いますか?

または、型を明示的に再帰関数に渡すこともできます。ジェネリック パラメーターで getType を使用するのではなく、既にプロパティの型から型を計算し、それを正しく渡しています (結局、プロパティがあるので手間がかかりません)。そのクラスを見つけるために)。

この回答はいくつかの仮定を立てていますが、観察可能な状況に適合しているので、それらが正しく、役立つことを願っています. 連絡がない場合は、編集または削除します。

于 2012-12-03T18:13:37.043 に答える