質問

私のアプリケーションには、異なるスキーマを持つ異なるデータベースに接続する複数のDataContextがあります。カスタムユーザーコントロールでは、クエリの結果を表示し、ユーザーが編集できるようにします。ユーザーがデータを編集するとき、データベースへの変更を永続化します。そのためには、ソースのDataContext(または少なくともソースのdatacontext型)への参照が必要なので、 DataContext.SubmitChanges();

を実行できます。

クエリがどのDataContextからのものかを判断する方法はありますか? DataQueryクラス自体は内部としてマークされているため、contextいリフレクションハックに頼らずにそのコンテキストプロパティにアクセスできないため、よりクリーンなアプローチを探しています。

この問題を回避する(いくつかの)方法があり、たとえばソースDataContextへの参照を渡しますが、これを行うにはもっと簡単な方法があるに違いないと思います。

編集: 次のコードは機能しますが、見苦しいです:

FieldInfo contextField = query.GetType().GetField("context", BindingFlags.Instance | BindingFlags.NonPublic);
if (query != null)
{
  queryContext = contextField.GetValue(value) as DataContext;
}
役に立ちましたか?

解決

DataContextをコードに(手動で)単に渡す必要があると思います。申し訳ありません。

他のヒント

はい-リフレクションを使用することは、クエリが属するDataContextを決定する唯一の方法です。クエリがトリガーされたときに作成されるデータオブジェクトでも同じです。

以下はルーンの質問に厳密に答えているわけではありませんが、リフレクションを使用して、データオブジェクトがデータコンテキストにアタッチおよび監視されているかどうかを判断する場合に役立ちます。

次のコードは、データオブジェクトに配置できるContextプロパティを定義し、オブジェクトが接続されているDataContext(存在する場合)を返すために使用されます。

Private Const StandardChangeTrackerName As String = "System.Data.Linq.ChangeTracker+StandardChangeTracker"

Private _context As DataClasses1DataContext
Public Property Context() As DataClasses1DataContext
    Get
        Dim hasContext As Boolean = False
        Dim myType As Type = Me.GetType()
        Dim propertyChangingField As FieldInfo = myType.GetField("PropertyChangingEvent", BindingFlags.NonPublic Or BindingFlags.Instance)
        Dim propertyChangingDelegate As PropertyChangingEventHandler = propertyChangingField.GetValue(Me)
        Dim delegateType As Type = Nothing

        For Each thisDelegate In propertyChangingDelegate.GetInvocationList()
            delegateType = thisDelegate.Target.GetType()
            If delegateType.FullName.Equals(StandardChangeTrackerName) Then
                propertyChangingDelegate = thisDelegate
                hasContext = True
                Exit For
            End If
        Next

        If hasContext Then
            Dim targetField = propertyChangingDelegate.Target
            Dim servicesField As FieldInfo = targetField.GetType().GetField("services", BindingFlags.NonPublic Or BindingFlags.Instance)
            If servicesField IsNot Nothing Then

                Dim servicesObject = servicesField.GetValue(targetField)

                Dim contextField As FieldInfo = servicesObject.GetType.GetField("context", BindingFlags.NonPublic Or BindingFlags.Instance)

                _context = contextField.GetValue(servicesObject)

            End If
        End If

        Return _context
    End Get
    Set(ByVal value As DataClasses1DataContext)

        _context = value

    End Set

End Property

オブジェクトは、ChangeTrackingがオンになっているコンテキストに現在アタッチされている場合にのみ、そのDataContextを見つけることができることに注意してください。このプロパティは、DataContextがオブジェクトのOnPropertyChangingイベントをサブスクライブして、オブジェクトの存続期間にわたる変更を監視しているという事実に依存しています。

これが役に立った場合は、この投稿に賛成票を投じてください。

リフレクションを使用してイベントハンドラーを見つける方法の詳細: http://weblogs.asp。 net / avnerk / archive / 2007/03/29 / reflecting-over-an-event.aspx http://www.bobpowell.net/eventsubscribers.htm

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top