Déterminer le DataContext source pour une requête Linq to Sql
-
11-07-2019 - |
Question
Dans mon application, plusieurs DataContexts se connectent à différentes bases de données avec différents schémas. Dans un contrôle utilisateur personnalisé, j'affiche les résultats de la requête et laisse l'utilisateur les modifier. Lorsque l'utilisateur modifie les données, je souhaite conserver les modifications apportées à la base de données. Pour ce faire, j'ai besoin d'une référence au DataContext source (ou au moins au type de source de données) afin de pouvoir effectuer un DataContext.SubmitChanges ();
Existe-t-il un moyen de déterminer de quel DataContext provient une requête? La classe DataQuery elle-même est marquée comme étant interne. Je ne peux donc pas accéder à sa propriété de contexte sans recourir à des piratages de réflexion laids. Je recherche donc une approche plus propre.
Il existe (plusieurs) moyens de contourner ce problème, en passant par exemple une référence au source DataContext, mais j’imagine qu’il doit exister un moyen plus simple de procéder.
Modifier: Le code suivant fonctionne, mais c'est moche:
FieldInfo contextField = query.GetType().GetField("context", BindingFlags.Instance | BindingFlags.NonPublic);
if (query != null)
{
queryContext = contextField.GetValue(value) as DataContext;
}
La solution
Je pense que vous allez simplement devoir passer le DataContext au code (manuellement). Désolé.
Autres conseils
Oui, l’utilisation de la réflexion est le seul moyen de déterminer le DataContext auquel appartient la requête. Il en va de même pour les objets de données créés lorsque la requête est déclenchée.
Ce qui suit ne répond pas strictement à la question de Rune, mais peut être utile si vous souhaitez utiliser la réflexion pour déterminer si un objet de données est attaché à et surveillé par un contexte de données:
Le code suivant définit une propriété Context qui peut être placée sur un objet de données, puis utilisée pour renvoyer le DataContext (le cas échéant) auquel l'objet est lié.
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
Notez que l'objet ne peut localiser son DataContext que s'il est actuellement lié au contexte avec ChangeTracking activé. Cette propriété repose sur le fait que le DataContext s'est abonné à l'événement OnPropertyChanging de l'objet pour surveiller les modifications sur la durée de vie de l'objet.
Si cela vous a été utile, votez pour cet article, s'il vous plaît.
Pour plus d'informations sur l'utilisation de la réflexion pour rechercher des gestionnaires d'événements: http: //weblogs.asp. net / avnerk / archive / 2007/03/29 / reflectant sur un événement.aspx http://www.bobpowell.net/eventsubscribers.htm