Determinare l'origine DataContext per una query da Linq a Sql
-
11-07-2019 - |
Domanda
Nella mia applicazione ho diversi DataContexts che si collegano a database diversi con schemi diversi. In un controllo utente personalizzato visualizzo i risultati della query e lascio che l'utente li modifichi, e quando l'utente modifica i dati, desidero mantenere le modifiche al database. Per fare ciò ho bisogno di un riferimento al DataContext di origine (o almeno al tipo di datacontext di origine) in modo da poter eseguire un DataContext.SubmitChanges();
Esiste un modo per determinare da quale DataContext proviene una query? La stessa classe DataQuery è contrassegnata come interna, quindi non posso accedere alla sua proprietà di contesto senza ricorrere a brutti hack di riflessione, quindi sto cercando un approccio più pulito.
Esistono (diversi) modi per aggirare questo problema, passando ad esempio un riferimento al DataContext di origine, ma immagino che ci debba essere un modo più semplice per farlo.
Modifica: Il seguente codice funziona, ma è brutto:
FieldInfo contextField = query.GetType().GetField("context", BindingFlags.Instance | BindingFlags.NonPublic);
if (query != null)
{
queryContext = contextField.GetValue(value) as DataContext;
}
Soluzione
Penso che dovrai semplicemente passare DataContext al codice (manualmente). Siamo spiacenti.
Altri suggerimenti
Sì: l'utilizzo di reflection è l'unico modo per determinare il DataContext a cui appartiene la query. È lo stesso con gli oggetti dati creati quando viene attivata la query.
Ciò che segue non risponde rigorosamente alla domanda di Rune, ma può essere utile se si desidera utilizzare la riflessione per determinare se un oggetto dati collegato e monitorato da un contesto dati:
Il codice seguente definisce una proprietà Context che può essere posizionata su un oggetto dati e quindi utilizzata per restituire il DataContext (se presente) a cui è collegato l'oggetto.
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
Prestare attenzione a notare che l'oggetto può individuare DataContext solo se è attualmente collegato al contesto con ChangeTracking attivato. Questa proprietà si basa sul fatto che DataContext ha sottoscritto l'evento OnPropertyChanging dell'oggetto per monitorare le modifiche durante la durata dell'oggetto.
Se questo è stato utile, per favore vota questo post.
Per ulteriori informazioni sull'uso di reflection per trovare i gestori di eventi: http: //weblogs.asp. net / avnerk / archive / 2007/03/29 / riflettendo-over-an-event.aspx http://www.bobpowell.net/eventsubscribers.htm