2013-02-28 10 views
13

Sto cercando di creare un metodo che converta una normale istruzione sql in oggetti C#, quindi ho deciso di utilizzare Irony per analizzare l'istruzione sql, quindi restituisco l'istruzione come azione che contiene il tipo di dichiarazione ei valori di esso a seconda del tipoAnalisi SQL con ironia

Ecco il mio non completato codice [perché ho ottenuto frustrato come io non so cosa fare allora]

private List<Action> ParseStatement(string statement) 
{ 
    var parser = new Parser(new SqlGrammar()); 
    var parsed = parser.Parse(statement); 
    var status = parsed.Status; 

    while (parsed.Status == ParseTreeStatus.Parsing) 
    { 
     Task.Yield(); 
    } 

    if (status == ParseTreeStatus.Error) 
     throw new ArgumentException("The statement cannot be parsed."); 

    ParseTreeNode parsedStmt = parsed.Root.ChildNodes[0]; 

    switch (parsedStmt.Term.Name) 
    { 
     case "insertStmt": 
      var table = parsedStmt.ChildNodes.Find(x => x.Term.Name == "Id").ChildNodes[0].Token.ValueString; 
      var valuesCount = 
       parsedStmt.ChildNodes.Find(x => x.Term.Name == "insertData").ChildNodes.Find(
        x => x.Term.Name == "exprList").ChildNodes.Count; 
      var values = parsedStmt.ChildNodes.Find(x => x.Term.Name == "insertData").ChildNodes.Find(
        x => x.Term.Name == "exprList").ChildNodes; 
      foreach (var value in values) 
      { 
       string type = value.Token.Terminal.Name; 
      } 
      break; 
    } 

    return null; 
} 

private Type ParseType(string type) 
{ 
    switch (type) 
    { 
     case "number": 
      return typeof (int); 
     case "string": 
      return typeof (string); 
    } 

    return null; 
} 

quindi la domanda è: come potrei usare Irony per convertire un'istruzione SQL stringa in oggetti aC#?

Ecco un esempio di quello che voglio ottenere:

INSERT INTO Persone VALORI (4, 'Nilsen', 'Johan', 'Bakken 2', 'Stavanger')

E ottenerlo convertito

return new Action<string type, string table, int val1, string val2, string val3, string val4, string val5>; 

dinamicamente a seconda di ciò che il metodo aver letto dalla dichiarazione.

Spero di aver spiegato bene la mia idea in modo che tu possa aiutarmi ragazzi, E se c'è qualcosa di poco chiaro per favore dimmelo e proverò a spiegarlo.

+5

Sto indovinando punto di partenza dovrebbe essere sempre un adeguato grammatica SQL e convertirla alla grammatica formato di ironia può capire. Non è roba facile. Sei pronto per un sacco di lavoro che non è per le persone facilmente frustrate. Ma * può * essere fatto. –

+0

Ho già SQLGrammar ma il problema è analizzare ogni istruzione, inserire, aggiornare, creare ... quindi restituire il suo contenuto [da utilizzare in C# in altri scopi] –

+0

La tua domanda si riferisce più a ottenere che Irony analizzi le tue istruzioni SQL o altro per eseguire la conversione in base ai risultati di analisi? Sei soddisfatto dell'AST che stai tornando da Irony? Potresti mostrare parte della grammatica SQL che stai utilizzando? –

risposta

1

Se non lo fai come un esercizio divertente, ti consiglio di utilizzare Linq in SQL per generare le tue classi di stub o Entity Framework come Drunken Code Monkey menzionato nei commenti.

Ecco un buon articolo per iniziare: Generating EF code from existing DB

1

stavo cercando di analizzare SQL con ironia pure. Ho rinunciato perché il parser di esempio SQL in Ironia Non maneggiare: CTE, Ordina per numero di colonna, la metà delle dichiarazioni speciali come

SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED 

Mentre ho avuto un grande momento conoscere Ironia, non ho il braciole di codifica per implementare correttamente tutte le parti sopra citate.

Ho finito per utilizzare la libreria di analisi SQL fornita da Microsoft. Codice di esempio per LINQPad 5 di seguito:

// Add a reference to 
// C:\Program Files (x86)\Microsoft SQL Server\130\SDK\Assemblies\ 
// Microsoft.SqlServer.TransactSql.ScriptDom.dll 
// 
// https://blogs.msdn.microsoft.com/gertd/2008/08/21/getting-to-the-crown-jewels/ 

public void Main() 
{ 
    var sqlFilePath = @"C:\Users\Colin\Documents\Vonigo\database-scripts\Client\Estimate\spClient_EstimateAddNew.sql"; 
    bool fQuotedIdenfifiers = false; 
    var parser = new TSql100Parser(fQuotedIdenfifiers); 

    string inputScript = File.ReadAllText(sqlFilePath); 
    IList<ParseError> errors; 
    using (StringReader sr = new StringReader(inputScript)) 
    { 
     var fragment = parser.Parse(sr, out errors); 
     fragment.Dump(); 
    } 
}