Metodi LINQPad [estensione]


144

Qualcuno ha un elenco completo di metodi e metodi di estensione LINQPad, come ad esempio

.Dump()

SubmitChanges()

1
Sto votando per chiudere questa domanda come fuori tema perché LINQPad è uno strumento in continua evoluzione, avendo una risposta solida e concreta e finale su questa domanda avrà una vita molto breve. Propongo di chiuderlo come off-topic per evitare di promuovere domande simili per altri strumenti.
Lasse V. Karlsen,

5
Non che io abbia nulla da dire sul voto, ma non sono certo d'accordo con la chiusura di questa risposta. Per prima cosa, guarda i voti per la domanda, quindi guarda i voti per i primi due commenti. Secondo, come possono le risposte di Joseph essere meno di una risposta finale; ha scritto la cosa. Infine, altre applicazioni utilizzano Stackoverflow per la loro documentazione. Uso sempre LinqPad per lo sviluppo, la prototipazione di query C # e Linq, l'esecuzione di SQL e l'esecuzione di attività Quick DBA e dozzine di altre cose. Quindi, almeno per me, le risposte sono sicuramente in tema.
EoRaptor013,

3
Per concludere: ho aggiunto più di una risposta a domande più vecchie su C # per fornire una tecnica più moderna che è stata introdotta nella lingua da quando è stata data risposta alla domanda. IMO dovremmo aspettarci che la base di conoscenza rappresentata da questo sito venga modificata e aggiornata man mano che la tecnologia avanza. La gamma di argomenti in cui i futuri aggiornamenti possono compromettere o annullare le risposte fornite in un determinato momento è piuttosto ampia: se chiudessimo tutte le domande in cui ciò potrebbe accadere, Stack Overflow sarebbe una risorsa molto più povera! Qui, un elenco completo può diventare un elenco parziale che è meglio di nessun elenco!
Bob Sammers,

Risposte:


255

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

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

È inoltre possibile specificare una profondità massima di ricorsione per sostituire il valore predefinito 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 IL, restituendo l'output in una stringa:

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

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

  • Cmd : esegue un comando shell o un programma esterno
  • CreateXhtmlWriter : crea un writer di testo che utilizza il formattatore Dump () di LINQPad
  • SqlOutputWriter : restituisce il writer di testo che scrive nella finestra di output SQL
  • GetMyQueries , GetSamples : restituisce una raccolta di oggetti che rappresentano le query / i campioni salvati (ad esempio, esegui una ricerca utilizzando Modifica | Cerca tutto)
  • Evidenzia : avvolge un oggetto in modo che venga evidenziato in giallo quando viene scaricato
  • HorizontalRun : consente di scaricare una serie di oggetti sulla stessa linea

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:user@domain.com", "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:

Dai un'occhiata a questo sito per le risposte alle domande di programmazione.

Il secondo scopo di HyperLinq è creare dinamicamente query:

// 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 su "Le mie query" e fai clic sulla query chiamata "Le mie estensioni". Tutti i tipi / metodi che definiscono 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 si fa clic sul collegamento, consentendo di reagire ad esso nel codice e non solo di collegarsi a pagine Web esterne.

DumpContainer è una classe che aggiunge un blocco nella finestra di output a cui può essere sostituito il contenuto.

NOTA! Ricordarsi .Dump()della DumpContainerstessa nel punto appropriato.

Usare:

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

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

NOTA! Ricorda .Dump()i risultati della chiamata OnDemandnel 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 procede.

NOTA! Ricordare .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);
}

33
Niente di meglio di una risposta dell'autore stesso!
Giovanni,

1
Joe, in realtà volevo anche prototipare alcuni lavori grafici e poi volevo scaricare una bitmap; sarebbe fantastico con un metodo Show per questo tipo di lavoro in cui si desidera un po 'di visualizzazione, lavorando su grafica, immagine, ecc. Possibilmente fornire visualizzazioni pulite per alcuni altri tipi lungo la strada.
Bent Rasmussen,

... In realtà, fintanto che puoi inviare elementi grafici al pannello di output, possiamo creare estensioni per il resto da soli.
Bent Rasmussen,

3
La 4.26 beta ti consente di iniettare XHTML nel flusso di output, chiamando Util.RawHtml. Vai a www.linqpad.net/beta.aspx (o attendi qualche giorno per RTM).
Joe Albahari,

1
Alex - per ottenere> 1 cosa su una linea, usa Util.HorizontalRun
Joe Albahari

131

Oltre al noto myQuery.Dump("Query result:"), un'altra caratteristica da menzionare è la Utilclasse: contiene molti metodi abbastanza utili (alcuni dei quali ho menzionato, ma ce ne sono molti altri).

Inoltre è interessante che puoi modificare il modo in cui Dump()funziona .

Infine, ti mostrerò come rendere permanenti le modifiche (ad es. Inserire, aggiornare, eliminare le query LINQ) utilizzando SubmitChanges()o SaveChanges()come accedere all'oggetto di connessione interno di LinqPad.

E per arrotondare, ti mostrerò come è possibile creare una semplice grafica 2d all'interno di LinqPad (disegnare linee, bitmap o funzioni ).

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


.Dump ()

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

Tutti gli utenti di LinqPad conoscono e adorano il .Dump()metodo di estensione, che consuma e stampa (quasi) tutto.

Ma sapevi che ci sono un paio di parametri disponibili? Dai un'occhiata a questo frammento 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

Le prime esempio stampe solo variabili ae ce nasconde be d, il 2 ° esempio fa il contrario (nota che specifica solo 2 dei parametri disponibili). Le variabili ye znon possono essere nascoste singolarmente, perché non sono al livello più alto.

Sono disponibili i seguenti parametri ( tutti facoltativi ):

  • description [stringa] - fornisce una descrizione per il dump dell'oggetto
  • depth [int?] - limita la profondità di ispezione ricorsiva degli oggetti
  • toDataGrid [bool] - se vero, l'output è formattato come datagrid anziché come RichText
  • exclude[stringa] - se si fornisce un elenco di variabili separato da virgole, verranno esclusi dall'output (nell'esempio "a, c": be dvengono visualizzati ae cnascosti)
  • exclude[stringa] con prefisso "+" - il prefisso inverte la logica del parametro exclude. Ciò significa che se si fornisce un elenco di variabili separato da virgole, tutte tranne quelle specificate vengono nascoste (nell'esempio "+ b, d": be dvengono visualizzate, tutte le altre nascoste)
  • archivia 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 si utilizza .OnDemand("click me").Dump();invece di .Dump(), verrà visualizzato un collegamento su cui è possibile fare clic per espandere. Utile se si desidera controllare i valori, ad esempio Util.OnDemand("Customer-ID: " + customerObject.ID.ToString(), ()=>customerObject, false).Dump();per mostrare sempre l'ID per impostazione predefinita, ma rivelare i dettagli customerObjectsolo se si è interessati.

Argomenti più avanzati su Dump sono disponibili qui e .


Ambiente

Questa non è un'estensione LinqPad, ma piuttosto una classe .NET, ma poiché è utile, lo citerò 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\UserNamevorrei usare System.Security.Principal.WindowsIdentity.GetCurrent().Name
piuttosto che Environment.UserDomainName+@"\"+Environment.UserName.


Util.WriteCsv

( novità: disponibile dalla versione LinqPad v4.45.05 (beta) )

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

Questo scriverà il contenuto della tabella Customersnel file CSV c:\temp\customers.csv. Puoi anche trovare un buon esempio su come usare Util.WriteCsve 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, è possibile utilizzare:
    var csvFile=Util.CurrentQueryPath.Replace(".linq", ".csv");

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

  • Se si desidera generare una tabella in formato XML anziché come file separato da virgole, è possibile farlo come segue :

    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();

    In questo esempio vengono restituiti tutti gli elementi con l'attributo attr1che contiene il valore "a"di 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");

Ciò recupererà la password dal gestore password integrato di LinqPad. Per creare e modificare la password, aprire il menu "Password Manager" nel menu "File" di LINQPad. Se non viene salvata alcuna password quando si esegue il codice C #, si aprirà una finestra di dialogo della password che richiede la password e si ha la possibilità di crearla e salvarla al volo selezionando la casella di controllo Salva password (nell'esempio, la password per "UserXY" verrebbe salvato e in seguito puoi trovare questa voce nel gestore delle password ).

I vantaggi sono che è possibile memorizzare la password negli script Linq creati in modo sicuro, separatamente e crittografati nel profilo utente di Windows (è archiviato %localappdata%\LINQPad\Passwordscome file). LinqPad utilizza DPAPI di Windows per proteggere la password.

Inoltre, la password viene archiviata centralmente, quindi se è necessario modificarla, è possibile farlo nel menu e si applica immediatamente a tutti gli script creati.

Appunti:

  • Se non si desidera salvare la password e visualizzare semplicemente una finestra di dialogo della password, è possibile utilizzare il secondo parametro nel modo seguente: In
    var pwd = Util.GetPassword("UserXY", true);
    questo modo la casella di controllo Salva password verrà deselezionata nella finestra di dialogo della password (tuttavia, l'utente è ancora in grado di controllarla e scegliere di salvare comunque).

  • Se richiedi che la password sia archiviata in a SecureString, puoi utilizzare questa funzione di supporto (nb: 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 che sia necessario .Dump. La sua memorizzazione in una variabile ha il vantaggio di poter utilizzare ulteriori query Linq su di essa. Per esempio:

var path=@"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();

Questo scaricherà tutti i file con estensione ".exe" o ".dll" contenuti in C:\windows\system32. L' /sopzione viene utilizzata per richiamare tutte le sottodirectory e /bviene utilizzata per il formato di output non elaborato. Si noti che il secondo parametro del metodo Cmd è specificato per sopprimere l'output della console al fine di mostrare solo il risultato filtrato utilizzando il metodo Dump.

Puoi vedere che questo è più flessibile dei caratteri jolly che hai con dirpoiché 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 filePath=@"C:\HelloWorld.txt";
Util.Cmd(@"%systemroot%\system32\notepad.exe", filePath);

Util.Image

Visualizza 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

L'uso Util.ProgressBarconsente di visualizzare una barra di avanzamento. È possibile 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, è possibile utilizzare Util.Progressper aggiornare la barra di avanzamento integrata di LinqPad, ad esempio:

Util.Progress = 25; // 25 percent complete

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


Util.RawHtml

Visualizza HTML nella finestra di output. Esempio:

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

Hyperlinq, Util.HorizontalRun

È possibile utilizzare 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 dell'editor preferito. Uso:

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

Nota che questa funzione è sempre attiva, mentre new Hyperlinq ("http://myURL", "Web site").Dump();non funziona per alcuni tipi di URL (in particolare, se devi passare nomi di porte 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 anche usare Console.ReadLine().

Ma c'è di più! È possibile creare un semplice parser JSON con il seguente frammento: molto utile, ad esempio se si desidera analizzare e testare una stringa JSON al volo. Salvare il seguente frammento come JSONAnalyzer.linq usando un editor di testo e quindi aprirlo 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à la Dumpfunzione per visualizzarlo correttamente come oggetto - e otterrai anche i messaggi di errore del parser sullo schermo per risolvere i problemi. Molto utile per il debug di AJAX.

JSON


Util.ClearResults

Se è necessario cancellare la finestra dei risultati all'interno dello script, utilizzare:

Util.ClearResults();

Utilizzalo nella parte superiore dello script oppure, se esegui più query in uno script, dovresti attendere l'input dell'utente prima di svuotare lo schermo (ad esempio, precedendolo con Util.ReadLine).


Custom .Dump () - ICustomMemberProvider

Inoltre è interessante poter cambiare l'output del .Dump()metodo. Basta implementare 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, ad esempio

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

allora il risultato sarà solo Hint, constMember1, constMember2, e myprop, ma non di proprietà xyz:

Dump Linqpad


Visualizzazione di un MessageBox o InputBox in LinqPad

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

Ad esempio, è possibile visualizzare un InputBox utilizzando il seguente codice

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.Run

( novità: disponibile dalla versione LinqPad v4.52.1 (beta) )

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

Esempi:

const string path=@"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 seguente codice di esempio:

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", "test@foo.com", "test@foo.com", "Test Subject" };
    #endif
    args.Dump("Args");
}

Consente di verificare se lo script è stato eseguito dall'interno della GUI di LinqPad o tramite lprun.exeo 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 operazioni di inserimento / aggiornamento / eliminazione ). Poiché il contesto del database è implicitamente creato da LinqPad, è necessario chiamare SubmitChanges()dopo ogni modifica come mostrato di seguito.

Esempi per il database (LinqPad-) Northwind :

Inserire

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

Aggiornare

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, è possibile 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 si utilizza Entity Framework , è possibile che si desideri rendere permanenti anche le modifiche (per operazioni di inserimento / aggiornamento / eliminazione ). 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 è necessario utilizzarli SaveChanges(), e anche per inserire ed eliminare i metodi sono cambiati.

Inserire

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

Aggiornare

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, è possibile 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 query. Ma a volte è utile fare riferimento in modo esplicito, ad esempio se si copia un codice dal progetto da Visual Studio e lo si incolla in LinqPad.

Lo snippet di codice preso dal progetto Visual Studio molto probabilmente è simile al seguente:

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

Ora, che cosa fare con dc? Naturalmente, è possibile rimuovere ogni occorrenza di dc.nella query, ma è molto più semplice. Aggiungi

var dc=this; // UserQuery

nella parte superiore dello 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à all'istante!


this.Connection

Utilizzando LinqPad con OleDb, convertendo un datatable in oggetto Linq, query SQL in Linq

Il seguente frammento di codice consente di utilizzare LinqPad con OleDb. Aggiungere System.Data.OleDbdalla System.Dataassemblea per le proprietà della query, quindi incollare il seguente codice 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 usare questo frammento 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 myDSin Linq, le risposte alla seguente domanda mostrano come farlo: Belli esempi di utilizzo della parola chiave dinamica .NET 4 con Linq

Un altro esempio: supponiamo che il tuo DBA ti dia una query SQL e desideri analizzare i risultati in LinqPad - ovviamente in Linq, non in SQL. Quindi è possibile effettuare le seguenti operazioni:

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 "inserita" nel testo del comando e i risultati vengono filtrati e ordinati per Città.
Naturalmente, questo è un esempio semplificato, il tuo DBA probabilmente ti darebbe uno script più complesso, ma stai ottenendo l'idea: basta aggiungere una classe di risultati di supporto che contiene tutti i campi dalla clausola SELECT e quindi puoi usarlo direttamente .
Puoi anche prendere il risultato da una procedura memorizzata in questo modo e usarlo in Linq. Come puoi vedere, in questo esempio non mi interessa il tipo di dati e lo uso dynamicper esprimerlo.
Quindi si tratta davvero di una programmazione rapida per poter analizzare rapidamente i dati. Non dovresti farlo nella tua vera applicazione per vari motivi (iniezione SQL, perché puoi usare EF dall'inizio ecc.).


PanelManager

Disegna grafica in LinqPad, parte 1

Per utilizzare gli esempi di seguito, premere F4e aggiungere System.Windows.dll, System.Windows.Forms.dll, WindowsFormsIntegration.dll, PresentationCore.dlle PresentationFramework.dllal vostro programma LINQPad e anche aggiungere lo spazio dei nomi System.Windows.Shapes.

Il primo esempio disegna 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 secondo esempio mostra come visualizzare gli elementi grafici in LinqPad usando PanelManager. Normalmente LinqPad supporta solo oggetti Wpf. Questo esempio usa System.Windows.Forms.Integration.WindowsFormsHostper rendere Windows.Forms.PictureBoxdisponibile (è 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à il seguente grafico (gli elementi del pannello "Grafica" e "Immagine" sono aggiunti dagli esempi sopra):

Showing_Graphic_in_LinqPad

Se si desidera visualizzare le immagini dal database Northwind, è possibile effettuare le seguenti operazioni:
Modificare il nome del file immagine in "NorthwindPics.jpg", quindi aggiungere il codice seguente all'inizio del metodo Main () del secondo esempio :

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 Employees e visualizzerà l'immagine.

Per ulteriori informazioni, consultare i seguenti collegamenti:
Forme e disegni di base nei visualizzatori personalizzati WPF
LinqPad

Nota: è possibile ottenere lo stesso risultato anche con 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 verrà aggiunta l'immagine.


Windows Form

Disegna grafica in LinqPad, parte 2

L'esempio seguente, ispirato a questo post, mostra come implementare un semplice plotter funzionale in Linqpad 5 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 usando la capacità di LinqPad per visualizzare i moduli di Windows nel pannello dei risultati. Aggiungere riferimenti (stampa ) : , , e aggiungere tutti gli spazi dei nomi da queste assemblee.
Esempio
F4
System.Drawing.dllSystem.Windows.Forms.dllSystem.Windows.Forms.DataVisualization.dll


Suggerimenti aggiuntivi / ulteriori letture:

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

  • Devi avere LinqPad come "app portatile" ? Leggi qui come farlo.

  • Il sito Web di Joe per LinqPad è sempre un'ottima fonte. All'interno di LinqPad, Help -> What's Newoffre suggerimenti su nuove funzioni e metodi. Il forum LinqPad contiene anche suggerimenti utili.

  • Anche molto utile: questo articolo sul debug di Linq (Pad).

  • Utilizzare lprun.exeper eseguire query LINQ negli 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 preparare anche query complesse usando -lang=programper attivare la modalità programma.

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


2
amo il suggerimento su Util.ReadLine <string> ("Enter some json"); Prima lo copiavo in un file e poi leggevo da lì ... Adoro questo consiglio. Grazie!
loneshark99,

2

Il dump è un metodo di estensione globale e SubmitChanges proviene dall'oggetto DataContext che è un oggetto System.Data.Linq.DataContext.

LP aggiunge solo Dump e 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.


Nota: nelle versioni più recenti di LinqPad: fare clic su .Dump()o su qualsiasi altro metodo nell'editor di origine, premere F12 per "riflettere". Questo è ora integrato nello strumento!
Matt,

1

Ho raggiunto il limite di testo StackOverflow nella mia risposta precedente , ma ci sono ancora estensioni più interessanti in LinqPad. Uno di questi vorrei menzionare:


Funzioni JavaScript (utilizzo .Dump())

Dalla versione 5.42 beta di LinqPad puoi incorporare funzioni JavaScript e chiamarle direttamente dal tuo codice C #. Sebbene ciò abbia alcune limitazioni (rispetto a JSFiddle), è un buon modo per testare rapidamente un codice JavaScript in LinqPad.

Esempio:

void Main()
{
    // JavaScript inside C#
    var literal = new LINQPad.Controls.Literal("script",
    @"function jsFoo(x) { 
        alert('jsFoo got parameter: ' + x); 
        var a = ['x', 'y', 'z']; external.log('Fetched \'' + a.pop() + '\' from Stack');
        external.log('message from C#: \'' + x + '\''); 
    }"); 
    // render & invoke
    literal.Dump().HtmlElement.InvokeScript(true, "jsFoo", "testparam");
}

In questo esempio, una funzione jsFoocon un parametro viene preparata e memorizzata nella variabile literal. Quindi, viene renderizzato e chiamato via .Dump().HtmlElement.InvokeScript(...), passando il parametro testparam.

La funzione JavaScript utilizza external.Log(...)per generare testo nelle finestre di output di LinqPad e alert(...)per visualizzare un messaggio popup.

Puoi semplificarlo aggiungendo i seguenti metodi / classi di estensione:

public static class ScriptExtension
{
    public static object RunJavaScript(this LINQPad.Controls.Literal literal, 
                                       string jsFunction, params object[] p)
    {
        return literal.Dump().HtmlElement.InvokeScript(true, jsFunction, p);
    }
    
    public static LINQPad.Controls.Literal CreateJavaScript(string jsFunction)
    {
        return new LINQPad.Controls.Literal("script", jsFunction);
    }
}

Quindi puoi chiamare l'esempio precedente come segue:

    // JavaScript inside C#
    var literal = ScriptExtension.CreateJavaScript(
    @"function jsFoo(x) { 
        alert('jsFoo got parameter: ' + x); 
        var a = ['x', 'y', 'z']; external.log('Fetched \'' + a.pop() + '\' from Stack');
        external.log('message from C#: \'' + x + '\''); 
    }"); 

    // render & invoke
    literal.RunJavaScript("jsFoo", "testparam");

Ha lo stesso effetto, ma è più facile da leggere (se hai intenzione di fare più JavaScript ;-)).

Un'altra opzione, se ti piacciono le espressioni Lambda e non ti piace specificare il nome della funzione come stringa ogni volta che la chiami, puoi fare:

var jsFoo = ScriptExtension.CreateJavaScript(
            @"function jsFoo(x) { ...  }"); 
ScriptExtension.RunJavaScript(() => jsFoo, "testparam");

purché tu abbia aggiunto la funzione di aiuto

public static object RunJavaScript(Expression<Func<LINQPad.Controls.Literal>> expr,  
                                   params object[] p)
{
    LINQPad.Controls.Literal exprValue = expr.Compile()();
    string jsFunction = ((MemberExpression)expr.Body).Member.Name;
    return exprValue.Dump().HtmlElement.InvokeScript(true, jsFunction, p);
}

alla classe ScriptExtension. Questo risolverà il nome della variabile che hai usato (qui jsFoo) che sembra avere lo stesso nome della funzione JavaScript stessa (Nota come viene utilizzata l'espressione lambda per risolvere il nome della variabile, ciò non può essere fatto usando nameof(paramName)all'interno della funzione).


.Dump () - aggiornamento di un messaggio in linea

A volte è utile sovrascrivere il testo scaricato invece di inserirlo in una nuova riga, ad esempio se si sta eseguendo una query di lunga durata e si desidera mostrarne l'avanzamento, ecc. (Vedere anche ProgressBar di seguito). Questo può essere fatto usando a DumpContainer, puoi usarlo come mostrato in

Esempio 1:

void Main()
{
   var dc = new DumpContainer("Doing something ... ").Dump("Some Action");
   System.Threading.Thread.Sleep(3000); // wait 3 seconds
   dc.Content += "Done.";
}

DumpContainerAnimation

Si noti che per alcuni oggetti più complessi, potrebbe essere necessario utilizzare dc.UpdateContent(obj);anziché dc.Content=....

Esempio 2:

void Main()
{
    var dc = new DumpContainer().Dump("Some Action");
    for (int i = 10; i >= 0; i--)
    {
        dc.UpdateContent($"Countdown: {i}");
        System.Threading.Thread.Sleep(250);
    };
    dc.UpdateContent("Ready for take off!");
}

Util.ProgressBar

La visualizzazione dell'avanzamento può essere eseguita anche utilizzando ProgressBar come segue:

Esempio:

void Main()
{
    var prog = new Util.ProgressBar("Processing").Dump();
    for (int i = 0; i < 101; i++)
    {
       Thread.Sleep(50); prog.Percent = i;
    }
    prog.Caption = "Done";
}

Questo è simile all'esempio di dump precedente, ma questa volta mostra una bella animazione con barra di avanzamento.


Test unitari con LinqPad - xUnit

Sapevi che puoi scrivere unit test in LinqPad? Ad esempio, è possibile utilizzare il framework xUnit. È disponibile tramite il supporto NUGET di LinqPad - tramite F4- nella finestra di dialogo Add NUGET..... Ecco una descrizione dettagliata su come usare xUnit con LinqPad V5 o V6.


Se ne scopro di più, aggiornerò questa risposta

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.