Metodi LINQPad [estensione].

 C Programming >> Programmazione C >  >> Tags >> LINQ
Metodi LINQPad [estensione].

LINQPad definisce due metodi di estensione (in LINQPad.Extensions), ovvero Dump() e Disassemble() . Dump() scrive nella finestra di output utilizzando il formattatore di output di LINQPad ed è sovraccaricato per consentire di specificare un'intestazione:

typeof (int).Assembly.Dump ();
typeof (int).Assembly.Dump ("mscorlib");

Puoi anche specificare una profondità di ricorsione massima per sovrascrivere l'impostazione predefinita di 5 livelli:

typeof (int).Assembly.Dump (1);              // Dump just one level deep
typeof (int).Assembly.Dump (7);              // Dump 7 levels deep
typeof (int).Assembly.Dump ("mscorlib", 7);  // Dump 7 levels deep with heading

Disassemble() disassembla qualsiasi metodo in IL , restituendo l'output in una stringa:

typeof (Uri).GetMethod ("GetHashCode").Disassemble().Dump();

Oltre a questi due metodi di estensione, in LINQPad.Util sono disponibili alcuni utili metodi statici. Questi sono documentati nel completamento automatico e includono:

  • Comando - esegue un comando di shell o un programma esterno
  • CreateXhtmlWriter - crea uno scrittore di testo che utilizza il formattatore Dump() di LINQPad
  • SqlOutputWriter - restituisce lo scrittore di testo che scrive nella finestra di output SQL
  • GetMyQuery , GetSamples - restituisce una raccolta di oggetti che rappresentano le query/campioni salvati (ad esempio, eseguire una ricerca utilizzando Modifica | Cerca tutto)
  • In evidenza - avvolge un oggetto in modo che venga evidenziato in giallo quando viene scaricato
  • Corsa orizzontale - ti consente di scaricare una serie di oggetti sulla stessa riga

LINQPad fornisce anche la classe HyperLinq. Questo ha due scopi:il primo è visualizzare i normali collegamenti ipertestuali:

new Hyperlinq ("www.linqpad.net").Dump();
new Hyperlinq ("www.linqpad.net", "Web site").Dump();
new Hyperlinq ("mailto:[email protected]", "Email").Dump();

Puoi combinarlo con Util.HorizontalRun :

Util.HorizontalRun (true,
  "Check out",
   new Hyperlinq ("http://stackoverflow.com", "this site"),
  "for answers to programming questions.").Dump();

Risultato:

Il secondo scopo di HyperLinq è creare query dinamicamente:

// Dynamically build simple expression:
new Hyperlinq (QueryLanguage.Expression, "123 * 234").Dump();

// Dynamically build query:
new Hyperlinq (QueryLanguage.Expression, @"from c in Customers
where c.Name.Length > 3
select c.Name", "Click to run!").Dump();

Puoi anche scrivere i tuoi metodi di estensione in LINQPad. Vai a "Le mie query" e fai clic sulla query chiamata "Le mie estensioni". Tutti i tipi/metodi definiti qui sono accessibili a tutte le query:

void Main()
{
  "hello".Pascal().Dump();  
}

public static class MyExtensions
{
  public static string Pascal (this string s)
  {
    return char.ToLower (s[0]) + s.Substring(1);
  }
}

In 4.46(.02) sono state introdotte nuove classi e metodi:

  • DumpContainer (classe)
  • OnDemand (metodo di estensione)
  • Util.ProgressBar (classe)

Inoltre, la classe Hyperlinq ora supporta un delegato Action che verrà chiamato quando fai clic sul collegamento, consentendoti di reagire ad esso nel codice e non solo di collegarti a pagine Web esterne.

DumpContainer è una classe che aggiunge un blocco nella finestra di output che può avere il suo contenuto sostituito.

NOTA! Ricordati di .Dump() il DumpContainer stesso nel punto appropriato.

Per utilizzare:

var dc = new DumpContainer();
dc.Content = "Test";
// further down in the code
dc.Content = "Another test";

OnDemand è un metodo di estensione che non emetterà il contenuto del suo parametro nella finestra di output, ma aggiungerà invece un collegamento cliccabile, che una volta cliccato sostituirà il collegamento con il .Dump() ed il contenuto del parametro. Questo è ottimo per strutture di dati a volte necessarie che sono costose o occupano molto spazio.

NOTA! Ricorda di .Dump() i risultati della chiamata a OnDemand nel punto appropriato.

Per usarlo:

Customers.OnDemand("Customers").Dump(); // description is optional

Util.ProgressBar è una classe che può mostrare una barra di avanzamento grafica all'interno della finestra di output, che può essere modificata man mano che il codice va avanti.

NOTA! Ricorda di .Dump() l'oggetto Util.ProgressBar nel punto appropriato.

Per usarlo:

var pb = new Util.ProgressBar("Analyzing data");
pb.Dump();
for (int index = 0; index <= 100; index++)
{
    pb.Percent = index;
    Thread.Sleep(100);
}

Parte 1 di 2

Oltre al noto myQuery.Dump("Query result:") , un'altra caratteristica da menzionare è il Util class:contiene molti metodi molto utili (alcuni li ho menzionati, ma ce ne sono molti di più).

Interessante anche la possibilità di modificare il modo Dump() funziona .

Infine ti mostrerò come puoi rendere le modifiche permanenti (ovvero inserire, aggiornare, eliminare query LINQ) utilizzando SubmitChanges() o SaveChanges() nonché come accedere all'oggetto di connessione interna di LinqPad.

Per concludere, ti mostrerò come creare semplici grafica 2D all'interno di LinqPad (disegnando linee, bitmap o funzioni ).

Quindi, ecco una raccolta di funzionalità integrate di LinqPad (dalla mia esperienza con lo strumento):

.Dump()

(parametri disponibili in LinqPad v5.03.08 e versioni successive)

Il .Dump() il metodo di estensione consuma e stampa (quasi) tutto.

Ma sapevi che sono disponibili un paio di parametri? Dai un'occhiata a questo snippet di codice:

var obj=new { a="Hello", b=5, c="World", d=new { y=5, z=10 } };
obj.Dump(description: "1st example", depth: 5, toDataGrid: false, exclude: "b,d");
obj.Dump("2nd example", exclude: "a,c");
obj.Dump("2nd example", exclude: "+b,d"); // new in V5.06.06 beta

Il 1° esempio stampa solo le variabili a e c e nasconde b e d , il 2° esempio fa il contrario (notare che specifica solo 2 dei parametri disponibili). Le variabiliy e z non possono essere nascosti individualmente, perché non sono al livello più alto.

Sono disponibili i seguenti parametri (tutti sono facoltativi ):

  • description [string] - fornisce una descrizione per l'oggetto da scaricare
  • depth [int?] - limita la profondità di ispezione ricorsiva degli oggetti
  • toDataGrid [bool] - se true, l'output è formattato come datagrid anziché come RichText
  • exclude [string] - se fornisci un elenco di variabili separate da virgole, queste verranno escluse dall'output (nell'esempio "a,c":b e d vengono visualizzati, a e c sono nascosti)
  • exclude [stringa] con prefisso "+" - il prefisso inverte la logica del parametro di esclusione. Ciò significa che, se fornisci un elenco di variabili separate da virgole, tutte tranne quelle specificate sono nascoste (nell'esempio "+b,d":b e d vengono mostrati, tutti gli altri nascosti)
  • memorizza le proprietà incluse ed escluse in una variabile (novità da LinqPad V5.09.04):
    var x=Util.ToExpando(obj, "a, c", "b, d"); x.Dump();
    La prima stringa contiene un elenco di proprietà da includere, la seconda stringa un elenco da escludere
  • espandi al clic:se utilizzi .OnDemand("click me").Dump(); invece di .Dump() , visualizzerà un collegamento su cui puoi fare clic per espandere. Utile se si desidera controllare i valori, ad es. Util.OnDemand("Customer-ID: " + customerObject.ID.ToString(), ()=>customerObject, false).Dump(); per mostrare sempre l'ID per impostazione predefinita ma rivelare i dettagli di customerObject solo se ti interessa.

Argomenti più avanzati su Dump possono essere trovati qua e là.

Ambiente

Questa non è un'estensione LinqPad, ma piuttosto una classe .NET, ma poiché è utile, la menzionerò comunque. Puoi ottenere molte informazioni utili che puoi utilizzare nei tuoi script come:

Environment.UserDomainName.Dump();
Environment.MachineName.Dump();
Environment.UserName.Dump();
Environment.CurrentDirectory.Dump();
Environment.SystemDirectory.Dump();

NB Per ottenere Domain\UserName Userei System.Security.Principal.WindowsIdentity.GetCurrent().Name
anziché [email protected]"\"+Environment.UserName .

Util.WriteCsv

(nuovo: disponibile dalla versione LinqPad v4.45.05 (beta))

Util.WriteCsv (Customers, @"c:\temp\customers.csv");

Questo scriverà il contenuto della tabella Customers nel file CSV c:\temp\customers.csv . Puoi anche trovare un bell'esempio su come usare Util.WriteCsv e quindi visualizzare i dati CSV nella finestra dei risultati di Linqpad qui.

Suggerimenti:

  • Per ottenere/creare un file CSV che si trova nella stessa directory della query, puoi utilizzare:
    var csvFile=Util.CurrentQueryPath.Replace(".linq", ".csv");

  • Se la tabella è grande, usa ObjectTrackingEnabled = false; prima di scrivere il CSV per evitare di memorizzarlo nella cache.

  • Se desideri generare una tabella in formato XML piuttosto che come file separato da virgole, puoi farlo come:

      var xmlFile=Util.CurrentQueryPath.Replace(".linq", ".xml");
      var xml = XElement.Load(xmlFile);
      var query =
        from e in xml.Elements()
        where e.Attribute("attr1").Value == "a"
        select e;
      query.Dump();
    

Questo esempio restituisce tutti gli elementi con l'attributo attr1 che contiene il valore "a" da un file XML che ha lo stesso nome della query ed è contenuto nello stesso percorso. Dai un'occhiata a questo link per altri esempi di codice.

Util.GetPassword

var pwd = Util.GetPassword("UserXY");

Questo recupererà la password dal gestore password integrato di LinqPad. Per creare e modificare la password, apri la voce di menu "Gestione password" nel menu "File" di LinqPad. Se non è stata salvata alcuna password quando esegui il codice C#, si aprirà una finestra di dialogo per la password che ti chiederà la password e potrai scegliere di crearla e salvarla al volo selezionando salva password checkbox (nell'esempio, la password per "UserXY" verrebbe salvata, e in seguito puoi trovare questa voce nel Gestione password ).

I vantaggi sono che puoi memorizzare la password nei LinqScript che crei in modo sicuro, separato e crittografato nel profilo utente di Windows (è memorizzato in %localappdata%\LINQPad\Passwords come file). LinqPad utilizza Windows DPAPI per proteggere la password.

Inoltre, la password è memorizzata centralmente, quindi se hai bisogno di cambiarla, puoi farlo nel menu e si applica immediatamente a tutti gli script che hai creato.

Note:

  • Se non si desidera salvare la password e aprire semplicemente una finestra di dialogo della password, è possibile utilizzare il 2° parametro come segue:
    var pwd = Util.GetPassword("UserXY", true);
    Questo deseleziona il salva password casella di controllo nella finestra di dialogo della password (tuttavia, l'utente può comunque selezionarla e scegliere di salvare comunque).

  • Se desideri che la password sia memorizzata in un SecureString , puoi utilizzare questa funzione di supporto (n.b.:per ottenere il metodo di estensione .ToSecureString() utilizzato, segui questo link su Stackoverflow - ti consente anche di riconvertirlo se necessario):
    System.Security.SecureString GetPasswordSecure(string Name, bool noDefaultSave=true)
    {
    return Util.GetPassword(Name, noDefaultSave) .ToSecureString();
    }

Util.Cmd

Questo metodo funziona come un processore di comandi. Puoi richiamare tutti i comandi che conosci dalla console di Windows.

Esempio 1 - dir:

Util.Cmd(@"dir C:\");

Questo produrrà il risultato della directory senza la necessità di .Dump esso. La memorizzazione in una variabile ha il vantaggio di poter utilizzare ulteriori query Linq su di essa. Ad esempio:

var [email protected]"C:\windows\system32"; 
var dirSwitch="/s/b";
var x=Util.Cmd(String.Format(@"dir ""{0}"" {1}", path, dirSwitch), true);
var q=from d in x 
        where d.Contains(".exe") || d.Contains(".dll")              
        orderby d
    select d;
q.Dump();

Verranno scaricati tutti i file con estensione ".exe" o ".dll" contenuti in C:\windows\system32 . Il /s switch viene utilizzato per ricorrere in modo ricorsivo a tutte le sottodirectory e /b viene utilizzato per il formato di output nudo. Si noti che il secondo parametro del metodo Cmd è specificato per sopprimere l'output della console in modo da mostrare solo il risultato filtrato utilizzando il metodo Dump.

Puoi vedere che questo è più flessibile dei caratteri jolly che hai con dir poiché puoi utilizzare la piena flessibilità del motore di query di Linq.

Esempio 2 - editor di testo:

Puoi aprire un file nel Blocco note in questo modo:

var [email protected]"C:\HelloWorld.txt";
Util.Cmd(@"%systemroot%\system32\notepad.exe", filePath);

Util.Image

Visualizza le immagini da un URL. Esempio:

var url = "http://chart.apis.google.com/chart?cht=p3&chd=s:Uf9a&chs=350x140&chl=January|February|March|April";
Util.Image(url).Dump();

Util.ProgressBar, Util.Progress

Usando Util.ProgressBar consente di visualizzare una barra di avanzamento. Puoi utilizzare la seguente classe di supporto:

public class ProgressBar
{
    Util.ProgressBar prog;
    
    public ProgressBar() 
    { 
        Init("Processing"); 
    }
    
    private void Init(string msg)
    {
        prog = new Util.ProgressBar (msg).Dump();
        prog.Percent=0;
    }

    public void Update(int percent)
    {
        Update(percent, null);
    }   
    
    public void Update(int percent, string msg)
    {
        prog.Percent=percent;
        if (String.IsNullOrEmpty(msg))
        {
            if (percent>99) prog.Caption="Done.";
        }
        else
        {
            prog.Caption=msg;
        }
    }
}

Usalo semplicemente come mostra il seguente esempio:

void Main()
{
    var pb1= new ProgressBar();
    Thread.Sleep(50);
    pb1.Update(50, "Doing something"); Thread.Sleep(550);
    pb1.Update(100); Thread.Sleep(50);
}

In alternativa puoi usare Util.Progress per aggiornare la barra di avanzamento integrata di LinqPads, ad esempio:

Util.Progress = 25; // 25 percent complete

La differenza è che non verrà visualizzato nella finestra dei risultati e non potrai assegnargli un messaggio.

Util.RawHtml

Visualizza l'HTML nella finestra di output. Esempio:

Util.RawHtml (new XElement ("h1", "This is a big heading")).Dump();

Hyperlinq, Util.HorizontalRun

Puoi usare questa funzione di esempio

public void ShowUrl(string strURL, string Title)
{
    Action showURL = delegate() { Process.Start("iexplore.exe", strURL); };
    var url = new Hyperlinq(showURL, "this link", true);
    Util.HorizontalRun (true, "Click ", url, " for details.").Dump(Title);
}

per mostrare i collegamenti ipertestuali nella finestra dei risultati o qualsiasi azione come l'apertura del tuo editor preferito.Utilizzo:

ShowUrl("http://stackoverflow.com", "Check out StackOverflow");

Nota che questa funzione funzioni sempre, mentre new Hyperlinq ("http://myURL", "Web site").Dump(); non funziona per alcuni tipi di URL (soprattutto se devi passare nomi di porta come ":1234" come parte dell'URL).

Util.ReadLine

Legge l'input dalla console. Esempio:

int age = Util.ReadLine<int> ("Enter your age");

Come sinonimo di Util.ReadLine<string>() , puoi usare Console.ReadLine() anche.

Ma c'è di più! Puoi creare un semplice parser JSON con il seguente snippet - abbastanza utile, ad esempio se vuoi analizzare e testare una stringa JSON al volo. Salva il seguente snippet come JSONAnalyzer.linq utilizzando un editor di testo e quindi aprilo in LinqPad (questo per aggiungere facilmente i riferimenti al volo):

<Query Kind="Program">
    <Reference>&lt;RuntimeDirectory&gt;\System.Web.Extensions.dll</Reference>
    <Namespace>System.Web.Script.Serialization</Namespace>
</Query>

void Main()
{
    var jsonData=Util.ReadLine<string>("Enter JSON string:");
    var jsonAsObject = new JavaScriptSerializer().Deserialize<object>(jsonData);
    jsonAsObject.Dump("Deserialized JSON");
}

Ora puoi eseguirlo e incollare semplicemente una stringa JSON dagli appunti nella console:utilizzerà il Dump funzione per visualizzarlo bene come un oggetto - e ricevi anche i messaggi di errore del parser sullo schermo per risolvere i problemi. Molto utile per il debug di AJAX.

Util.ClearResults

Se devi cancellare la finestra dei risultati all'interno del tuo script, usa:

Util.ClearResults();

Usalo nella parte superiore del tuo script oppure, se stai eseguendo più query in uno script, dovresti attendere l'input dell'utente prima di oscurare lo schermo (ad es. precedendolo con Util.ReadLine ).

Dump personalizzato() - ICustomMemberProvider

Interessante anche la possibilità di modificare l'output del .Dump() metodo. Implementa semplicemente l'interfaccia ICustomMemberProvider , ad es.

public class test : ICustomMemberProvider 
{

      IEnumerable<string> ICustomMemberProvider.GetNames() {
        return new List<string>{"Hint", "constMember1", "constMember2", "myprop"};
      }
      
      IEnumerable<Type> ICustomMemberProvider.GetTypes() 
      {
        return new List<Type>{typeof(string), typeof(string[]), 
            typeof(string), typeof(string)};
      }
      
      IEnumerable<object> ICustomMemberProvider.GetValues() 
      {
        return new List<object>{
        "This class contains custom properties for .Dump()", 
        new string[]{"A", "B", "C"}, "blabla", abc};
      }

      public string abc = "Hello1"; // abc is shown as "myprop"
      public string xyz = "Hello2"; // xyz is entirely hidden
}

Se crei un'istanza di questa classe, come

var obj1 = new test();
obj1.Dump("Test");

quindi produrrà solo Hint , constMember1 , constMember2 e myprop , ma non la proprietà xyz :

Visualizzazione di un MessageBox o di un InputBox in LinqPad

Se hai bisogno di visualizzare una finestra di messaggio, guarda qui come farlo.

Ad esempio, puoi visualizzare un InputBox utilizzando il codice seguente

void Main()
{
    string inputValue="John Doe"; 
    inputValue=Interaction.InputBox("Enter user name", "Query", inputValue);
    if (!string.IsNullOrEmpty(inputValue)) // not cancelled and value entered
    {
        inputValue.Dump("You have entered;"); // either display it in results window
        Interaction.MsgBox(inputValue, MsgBoxStyle.OkOnly, "Result"); // or as MsgBox
    }
}

(non dimenticare di premere F4 e aggiungere Microsoft.VisualBasic.dll e i suoi spazi dei nomi per farlo funzionare)

Util.Esegui

(nuovo: disponibile dalla versione LinqPad v4.52.1 (beta))

Consente di eseguire un altro script LINQPad dall'interno dello script o dal proprio programma .NET o servizio Windows (facendo riferimento alla versione LINQPad4-AnyCPU di LINQPad.exe ). Esegue lo script proprio come lo strumento da riga di comando lprun.exe lo farebbe.

Esempi:

const string [email protected]"C:\myScripts\LinqPad\";
var dummy=new LINQPad.QueryResultFormat(); // needed to call Util.Run
Util.Run(path+"foo.linq", dummy);

Questo esempio esegue lo script foo.linq , che contiene il codice di esempio seguente:

void Main(string[] args)
{
    #if CMD
       "I'm been called from lprun! (command line)".Dump();
    #else
       "I'm running in the LINQPad GUI!".Dump();
       args = new[] { "testhost", "[email protected]", "[email protected]", "Test Subject" };
    #endif
    args.Dump("Args");
}

Ti consente di verificare se lo script è stato eseguito dall'interno della GUI di LinqPad o tramite lprun.exe o con Util.Run .

Nota: Le seguenti varianti di invocazione potrebbero essere utili:

Util.Run(path+"foo.linq", dummy).Dump(); // obviously dumps the script output!
Util.Run(path+"foo.linq", dummy).Save(path+"foo.log"); // writes output into log
Util.Run(path+"foo.linq", dummy).SaveAsync(path+"foo1.log");     // async output log

SubmitChanges() - Linq a SQL

Se stai usando LinqToSQL , potresti voler rendere permanenti le modifiche (per inserire/aggiornare/eliminare operazioni). Poiché il contesto del database è implicitamente creato da LinqPad, è necessario chiamare SubmitChanges() dopo ogni modifica come mostrato di seguito.

Esempi per (LinqPad-)Northwind banca dati:

Inserisci

var newP = new Products() { ProductID=pID, CategoryID=cID, 
            ProductName="Salmon#"+pID.ToString() };
Products.InsertOnSubmit(newP);
SubmitChanges();    

Aggiorna

var prod=(from p in Products
            where p.ProductName.Contains("Salmon")
            select p).FirstOrDefault();
prod.ProductName="Trout#"+prod.ProductID.ToString();
SubmitChanges(); 

Elimina

var itemsToDelete=Products.Where(p=> p.ProductName.Contains("Salmon") ||
    p.ProductName.Contains("Trout"));
foreach(var item in itemsToDelete) { Products.DeleteOnSubmit(item); }
SubmitChanges();

Nota: Per ottenere ID validi per gli esempi precedenti, puoi utilizzare:

var cID = (from c in Categories 
            where c.CategoryName.Contains("Seafood") 
            select c).FirstOrDefault().CategoryID;

var pID = Products.Count()+1;

prima di invocarli.

SaveChanges() - Entity Framework

Se stai utilizzando Entity Framework , potresti anche voler rendere permanenti le modifiche (per insert/update/delete operazioni). Poiché il contesto del database è implicitamente creato da LinqPad, è necessario chiamare SaveChanges() dopo ogni modifica come mostrato di seguito.

Gli esempi sono sostanzialmente gli stessi di prima per LinqToSQL , ma devi usare SaveChanges() invece, e per inserire ed eliminare anche i metodi sono cambiati.

Inserisci

var newP = new Products() { ProductID=pID, CategoryID=cID, 
            ProductName="Salmon#"+pID.ToString() };
Products.Add(newP);
SaveChanges();  

Aggiorna

var prod=(from p in Products
            where p.ProductName.Contains("Salmon")
            select p).FirstOrDefault();
prod.ProductName="Trout#"+prod.ProductID.ToString();
SaveChanges(); 

Elimina

var itemsToDelete=Products.Where(p=> p.ProductName.Contains("Salmon") ||
    p.ProductName.Contains("Trout"));
foreach(var item in itemsToDelete) { Products.Remove(item); }
SaveChanges();

Nota: Per ottenere ID validi per gli esempi precedenti, puoi utilizzare:

var cID = (from c in Categories 
            where c.CategoryName.Contains("Seafood") 
            select c).FirstOrDefault().CategoryID;

var pID = Products.Count()+1;

prima di invocarli.

questo - contesto del database

In LinqPad , il contesto del database viene applicato automaticamente utilizzando la casella combinata in alto e selezionando il database giusto per la tua query. Ma a volte è utile fare riferimento ad esso in modo esplicito, ad esempio se copi del codice dal tuo progetto da Visual Studio> e incollalo in LinqPad.

Il tuo frammento di codice preso dal progetto di Visual Studio molto probabilmente assomiglia a questo:

var prod=(from p in dc.Products
            where p.ProductName.Contains("Salmon")
            select p).FirstOrDefault();
prod.ProductName="Trout#"+prod.ProductID.ToString();
dc.SaveChanges(); 

Ora cosa fare con dc ? Ovviamente puoi rimuovere ogni occorrenza di dc. nella tua query, ma è molto più semplice. Basta aggiungere

var dc=this; // UserQuery

nella parte superiore del tuo snippet in questo modo:

void Main()
{
    var dc=this;
    var prod=(from p in dc.Products
                where p.ProductName.Contains("Salmon")
                select p).FirstOrDefault();
    prod.ProductName="Trout#"+prod.ProductID.ToString();
    dc.SaveChanges(); 
}   

e il codice funzionerà immediatamente!

questa.connessione

Utilizzo di LinqPad con OleDb, conversione di un datatable in oggetto Linq, query SQL in Linq

Il seguente frammento di codice ti aiuta a usare LinqPad con OleDb. Aggiungi System.Data.OleDb dal System.Data assembly nelle proprietà della query, quindi incolla il codice seguente in Main() :

var connStr="Provider=SQLOLEDB.1;"+this.Connection.ConnectionString; 

OleDbConnection conn = new OleDbConnection(connStr);
DataSet myDS = new DataSet();
conn.Open();

string sql = @"SELECT * from Customers";
OleDbDataAdapter adpt = new OleDbDataAdapter();
adpt.SelectCommand = new OleDbCommand(sql, conn); 
adpt.Fill(myDS);

myDS.Dump();

Ora aggiungi una connessione SqlServer a LinqPad e aggiungi il database Northwind per eseguire questo esempio.

NB: Se vuoi solo ottenere il database e il server della connessione attualmente selezionata, puoi utilizzare questo snippet di codice:

void Main()
{
    var dc=this;
    var tgtSrv=dc.Connection.DataSource;
    var tgtDb=dc.Connection.ConnectionString.Split(';').Select(s=>s.Trim())
        .Where(x=>x.StartsWith("initial catalog", StringComparison.InvariantCultureIgnoreCase))
        .ToArray()[0].Split('=')[1];
    tgtSrv.Dump();
    tgtDb.Dump();
}

Puoi persino convertire myDS in Linq, le risposte alla seguente domanda mostrano come farlo:Bellissimi esempi di utilizzo della parola chiave dinamica .NET 4 con Linq

Un altro esempio:supponiamo che il tuo DBA ti fornisca una query SQL e desideri analizzare i risultati in LinqPad, ovviamente in Linq, non in SQL. Puoi fare quanto segue:

void Main()
{
    var dc=this;
    
    // do the SQL query
    var cmd =
        "SELECT Orders.OrderID, Orders.CustomerID, Customers.CompanyName,"
        +"       Customers.Address, Customers.City"
        +" FROM Customers INNER JOIN Orders ON Customers.CustomerID = Orders.CustomerID";
    var results = dc.ExecuteQuery<OrderResult>(cmd);
    
    // just get the cities back, ordered ascending
    results.Select(x=>x.City).Distinct().OrderBy(x=>x).Dump();
}

class OrderResult
{   // put here all the fields you're returning from the SELECT
    public dynamic OrderID=null; 
    public dynamic CustomerID=null;
    public dynamic CompanyName=null;
    public dynamic Address=null;
    public dynamic City=null;
}

In questo esempio, la query SELECT del DBA viene semplicemente "gettata" nel testo del comando e i risultati vengono filtrati e ordinati per città.
Ovviamente, questo è un esempio semplificato, il tuo DBA probabilmente ti darebbe uno script più complesso, ma ti stai facendo un'idea:aggiungi una classe di risultati di supporto che contiene tutti i campi della clausola SELECT, quindi puoi usarla direttamente.
Puoi anche prendere il risultato da una stored procedure in questo modo e usarlo in Linq. Come puoi vedere, in questo esempio non mi interessa il tipo di dati e utilizzo dynamic per esprimerlo.
Quindi si tratta davvero di una programmazione rapida per poter analizzare i dati rapidamente. Non dovresti farlo nella tua applicazione reale per vari motivi (SQL injection, perché puoi usare EF dall'inizio ecc.).

Gestione pannello

Disegna grafica in LinqPad, parte 1

Per utilizzare gli esempi seguenti, premi F4 e aggiungi System.Windows.dll , System.Windows.Forms.dll , WindowsFormsIntegration.dll , PresentationCore.dll e PresentationFramework.dll al tuo programma LinqPad e aggiungi anche lo spazio dei nomi System.Windows.Shapes .

Il 1° esempio traccia semplicemente una linea:

var myLine = new Line();
myLine.Stroke = System.Windows.Media.Brushes.LightSteelBlue;
myLine.X1 = 1; myLine.X2 = 50;
myLine.Y1 = 1; myLine.Y2 = 50;
myLine.StrokeThickness = 2;
PanelManager.DisplayWpfElement(myLine, "Graphic");

Il 2° esempio mostra come visualizzare la grafica in LinqPad utilizzando PanelManager. Normalmente LinqPad supporta solo oggetti Wpf. Questo esempio utilizza System.Windows.Forms.Integration.WindowsFormsHost per creare un PictureBox disponibile (è stato ispirato da questo):

// needs (F4): System.Windows.dll, System.Windows.Forms.dll, 
// WindowsFormsIntegration.dll, PresentationCore.dll, PresentationFramework.dll 
void Main()
{       
    var wfHost1 = new System.Windows.Forms.Integration.WindowsFormsHost();
    wfHost1.Height=175; wfHost1.Width=175; wfHost1.Name="Picturebox1";
    wfHost1.HorizontalAlignment=System.Windows.HorizontalAlignment.Left;
    wfHost1.VerticalAlignment=System.Windows.VerticalAlignment.Top;
    System.Windows.Forms.PictureBox pBox1 = new System.Windows.Forms.PictureBox();
    wfHost1.Child = pBox1;
    pBox1.Paint += new System.Windows.Forms.PaintEventHandler(picturebox1_Paint);
    PanelManager.StackWpfElement(wfHost1, "Picture");
} 

public string pathImg
{
    get { return System.IO.Path.Combine(@"C:\Users\Public\Pictures\Sample Pictures\", 
            "Tulips.jpg"); } 
}

// Define other methods and classes here
public void picturebox1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
    // https://stackoverflow.com/a/14143574/1016343
    System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(pathImg);
    System.Drawing.Point ulPoint = new System.Drawing.Point(0, 0);
    e.Graphics.DrawImage(bmp, ulPoint.X, ulPoint.Y, 175, 175);
}

Questo creerà la seguente grafica (le voci del pannello "Grafica" e "Immagine" vengono aggiunte dagli esempi precedenti):

Se desideri visualizzare le immagini dal database Northwind, puoi fare quanto segue:
Modifica il nome del file immagine in "NorthwindPics.jpg", quindi aggiungi il codice seguente all'inizio del 2° esempio Metodo Main():

var img = (from e in this.Employees select e).FirstOrDefault().Photo.ToArray();
using (FileStream fs1 = new FileStream(pathImg, FileMode.Create))
{
    const int offset=78;
    fs1.Write(img, offset, img.Length-offset);
    fs1.Close();
}

Leggerà il primo record dalla tabella Impiegati e visualizzerà l'immagine.

Dai un'occhiata ai seguenti link per saperne di più:
Forme e disegno di base in WPF
Visualizzatori personalizzati LinqPad

Nota: Puoi ottenere lo stesso risultato anche senza PanelManager, come mostra il seguente esempio, che ho visto qui:

// using System.Drawing;
using (var image=new Bitmap(100, 100))
using (var gr = Graphics.FromImage(image))
{
    gr.FillRectangle(Brushes.Gold, 0, 0, 100, 100);
    gr.DrawEllipse(Pens.Blue, 5, 5, 90, 90);
    gr.Save();
    image.Dump();
}

Sta usando il .Dump() comando per visualizzarlo. Puoi invocare image.Dump() più volte e aggiungerà l'immagine.

Moduli Windows

Disegna grafica in LinqPad, parte 2

Il seguente esempio, ispirato da questo post, mostra come implementare un plotter di funzioni in Linqpad usando C#7:

void Main()
{
    fnPlotter(x1: -1, x2: 1, fn: (double x) => Math.Pow(x, 3)).Dump();
}

public static Bitmap fnPlotter(double x1=-3, double x2=3, double s=0.05, 
                                   double? ymin=null, double? ymax=null, 
                                   Func<double, double> fn = null, bool enable3D=true)
{
    ymin = ymin ?? x1; ymax = ymax ?? x2;
    
    dynamic fArrPair(double p_x1 = -3, double p_x2 = 3, double p_s = 0.01, 
                          Func<double, double> p_fn = null)
    {
        if (p_fn == null) p_fn = ((xf) => { return xf; }); // identity as default
        var xl = new List<double>(); var yl = new List<double>();
        for (var x = p_x1; x <= p_x2; x += p_s)
        {
            double? f = null;
            try { f = p_fn(x); }
            finally
            {
                if (f.HasValue) { xl.Add(x); yl.Add(f.Value); }
            }
        }
        return new { Xs = xl.ToArray(), Ys = yl.ToArray() };
    }

    var chrt = new Chart(); var ca = new ChartArea(); chrt.ChartAreas.Add(ca);
    ca.Area3DStyle.Enable3D = enable3D;
    ca.AxisX.Minimum = x1; ca.AxisX.Maximum = x2;   
    ca.AxisY.Minimum = ymin.Value; ca.AxisY.Maximum = ymax.Value;
        
    var sr = new Series(); chrt.Series.Add(sr);
    sr.ChartType = SeriesChartType.Spline; sr.Color = Color.Red;
    sr.MarkerColor = Color.Blue; sr.MarkerStyle = MarkerStyle.Circle;
    sr.MarkerSize = 2;
                
    var data = fArrPair(x1, x2, s, fn); sr.Points.DataBindXY(data.Xs, data.Ys); 
    var bm = new Bitmap(width: chrt.Width, height: chrt.Height);
    chrt.DrawToBitmap(bm, chrt.Bounds); return bm;
}

Sta utilizzando la capacità di LinqPad di visualizzare i moduli di Windows nel pannello dei risultati.

Aggiungi riferimenti (premi F4 ) :
System.Drawing.dll , System.Windows.Forms.dll , System.Windows.Forms.DataVisualization.dll
e aggiungi tutti gli spazi dei nomi da questi assembly.

Ulteriori suggerimenti/ulteriori letture:

  • Vuoi utilizzare LinqPad in Visual Studio ? Ecco come puoi farlo.

  • È necessario disporre di LinqPad come "App portatile" ? Leggi qui come farlo.

  • Il sito Web di Joe per LinqPad è una fonte eccellente. All'interno di LinqPad, Help -> What's New fornisce suggerimenti su nuove funzioni e metodi. Il forum LinqPad contiene anche suggerimenti utili.

  • Utile anche:questo articolo sul debug di Linq(Pad).

  • Usa lprun.exe per esecuzione di query LINQ nei tuoi script batch. Leggi questo articolo per maggiori dettagli. Ad esempio:
    echo Customers.Take(100) > script.txt
    lprun -lang=e -cxname=CompanyServer.CustomerDb script.txt
    In questo esempio, la query è una semplice espressione LINQ. Ovviamente puoi anche preparare query complesse utilizzando -lang=program per attivare la modalità programma.

  • Puoi scrivere e memorizzare metodi di estensione in Le mie query scheda sul lato sinistro di LinqPad:l'ultimo elemento dell'albero è denominato Le mie estensioni; fai doppio clic su di esso per aprire un file in cui puoi scrivere estensioni disponibili per tutte le tue query. Inseriscili nella classe statica pubblica MyExtensions e usa il Main() metodo per includere i test per le tue estensioni.

Continua qui...


Dump è un metodo di estensione globale e SubmitChanges deriva dall'oggetto DataContext che è un oggetto System.Data.Linq.DataContext.

LP aggiunge solo Dump and Disassemble per quanto ne so. Anche se consiglio vivamente di aprirlo in Reflector per vedere cos'altro c'è che può essere utilizzato. Una delle cose più interessanti è lo spazio dei nomi LINQPad.Util che ha alcune chicche utilizzate internamente da LINQPad.