2014-11-19 79 views
6

Uso LinqPad con il driver MySQL IQ per interrogare i dati da un database Magento. Non solo uso questo per i rapporti sul database ma per fare gli aggiornamenti. Posso utilizzare il metodo standard SubmitChanges() per aggiornare i dati, ma spesso si tratta di aggiornamenti insopportabilmente lenti che possono richiedere letteralmente ore: una delle mie tabelle ha 35.707 record che ricrei regolarmente.Esegui una query simile a `Hyperlinq` in LinqPad a livello di codice

Quindi, invece, genera istruzioni SQL nelle query di LinqPad e quindi le eseguo in una scheda separata dopo aver selezionato "SQL" nel menu a discesa della lingua.

Per esempio, la mia uscita potrebbe essere qualcosa di simile:

UPDATE catalog_category_product SET position = 6040 WHERE (category_id = 156 AND product_id = 12648); 
UPDATE catalog_product_entity_media_gallery_value SET label = 'Sandy Beach' WHERE ((store_id = 0) AND (value_id = 8791)); 
-- Done. 

Di recente ho scoperto che LINQPad ha una bella classe chiamata Hyperlinq che mi permette di scrivere codice come questo:

(new Hyperlinq(QueryLanguage.SQL, myGeneratedSqlText, "Run Query")).Dump(); 

Il risultato è che un hyperlinq viene inserito nella finestra di output che eseguirà la query (nel mio esempio il contenuto di myGeneratedSqlText) in una nuova scheda ed eseguirà la query.

Questo è molto conveniente.

Tuttavia, ora desidero poter salvare un registro delle query eseguite. Non sembra esserci (un modo facile) integrato per eseguire manualmente una query "generata" in LinqPad. Posso certamente usare Util.Run per eseguire una query salvata esistente, in realtà faccio qualcosa di simile:

Util 
    .OnDemand("Run Query",() => 
    { 
     var fn = createOutputQueryFileName(); // Timestamped query name 
     System.IO.File.WriteAllText(fn, myGeneratedSqlText); 
     var run = Util.Run(fn, QueryResultFormat.Text); 
     var result = run.AsString(); 
     return result.StartsWith("[]") ? "Success" : result; 
    }) 
    .Dump(); 

L'unico dramma con questo è che devo anteporre il testo in myGeneratedSqlText con il seguente:

var preamble = @"<Query Kind=""SQL""> 
    <Connection> 
    <ID>ec026b74-8d58-4214-b603-6d3145e03d7e</ID> 
    <Driver Assembly=""IQDriver"" PublicKeyToken=""5b59726538a49684"">IQDriver.IQDriver</Driver> 
    <Provider>Devart.Data.MySql</Provider> 
    <CustomCxString>[DELETED]</CustomCxString> 
    <Server>127.0.0.1</Server> 
    <Database>prod_1_8</Database> 
    <Password>[DELETED]</Password> 
    <UserName>[DELETED]</UserName> 
    <NoPluralization>true</NoPluralization> 
    <NoCapitalization>true</NoCapitalization> 
    <DisplayName>Production Tunnel</DisplayName> 
    <EncryptCustomCxString>true</EncryptCustomCxString> 
    <Persist>true</Persist> 
    <DriverData> 
     <StripUnderscores>false</StripUnderscores> 
     <QuietenAllCaps>false</QuietenAllCaps> 
     <Port>6606</Port> 
    </DriverData> 
    </Connection> 
</Query> 
"; 

vorrei davvero evitare tutte queste cose preambolo e includere una linea come questa nel mio codice Util.OnDemand(...):

var run = Util.Run(QueryLanguage.SQL, myGeneratedSqlText, QueryResultFormat.Text); 

(Ma questo metodo non esiste.)

Il requisito chiave qui è quello di visualizzare un hyperlinq nella finestra di output di LinqPad che, se cliccato, salverà la query sul disco come un log ed eseguirà anche la query.

Qualcuno può suggerire un modo pulito per me di farlo?

+1

Una nota minore sul "preambolo": non è necessario includere tutti gli elementi in . L'elemento è sufficiente se la connessione è definita su quella macchina. –

+1

Un altro modo per ottenere il preambolo è questo: var reader = XmlReader.Create (Util.CurrentQueryPath, nuovo XmlReaderSettings {ConformanceLevel = ConformanceLevel.Fragment}); reader.Read(); string preamble = XElement.ReadFrom (reader) .ToString(); –

risposta

2

Spero di aver capito bene. Quando hai selezionato una connessione nella barra in alto, la tua UserQuery diventa un datacontext. Per questo motivo, è possibile utilizzare ExecuteQuery ed ExecuteCommand su questo all'interno di un'azione Hyperlinq basata su azioni.

new Hyperlinq(() => { 
       "do log work here".Dump(); 
       this.ExecuteQuery<string>(generatedSelect).Dump("Results"); 
       this.ExecuteCommand(generatedCommand).Dump("Results"); 
      }, "Run Query").Dump(); 

Purtroppo questo uscite agli scheda corrente, ma spero che questo si sarà almeno avere la maggior parte del modo di fare :)

Ecco un'immagine di esso al lavoro:

Example

Come si sta utilizzando MySQL, si può andare via la proprietà di connessione su questo:

new Hyperlinq(() => { 
      "do log work here".Dump(); 
      using (var command = this.Connection.CreateCommand()) 
      { 
       // Usual command logic here 
      } 
     }, "Run Query").Dump(); 
+0

Grazie per la risposta, ma non riesco a trovare i metodi 'ExecuteQuery' o' ExecuteCommand' sotto 'this'. Puoi verificare se questo codice funziona per te? – Enigmativity

+1

Funziona per me, ma solo se ho selezionato prima una connessione (altrimenti UserQuery non deriva da un contesto dati) –

+0

Aggiunta un'immagine al lavoro. Notando che ho una connessione. Nell'immagine ho già cliccato il link Run Query –