Métodos LINQPad [extensão]

144

Alguém tem uma lista completa dos métodos e métodos de extensão LINQPad, como

.Dump()

SubmitChanges()
Bent Rasmussen
fonte
1
Estou votando para encerrar esta questão como fora de tópico, porque o LINQPad é uma ferramenta em constante mudança. Ter uma resposta sólida, concreta e final sobre essa questão terá uma vida muito curta. Proponho encerrá-lo como off-topic para evitar promover perguntas semelhantes para outras ferramentas.
Lasse V. Karlsen
5
Não que eu tenha algo a dizer sobre votação, mas certamente não concordo em fechar esta resposta. Primeiro, basta olhar para os votos positivos da pergunta e, em seguida, olhar para os votos positivos dos dois primeiros comentários. Segundo, como as respostas de Joseph podem ser menos que uma resposta final; ele escreveu a coisa. Por fim, outros aplicativos usam o Stackoverflow para sua documentação. Uso o LinqPad para desenvolvimento o tempo todo, criando protótipos de consultas em C # e Linq, executando SQL e executando tarefas de Quick DBA e dezenas de outras coisas. Então, pelo menos para mim, as respostas estão definitivamente no tópico.
EoRaptor013
3
Para encerrar: adicionei mais de uma resposta às perguntas mais antigas sobre C # para fornecer uma técnica mais moderna que foi introduzida no idioma desde que a pergunta foi respondida. Na IMO, devemos esperar que a base de conhecimento que este site represente seja modificada e atualizada à medida que a tecnologia avança. A variedade de tópicos em que futuras atualizações podem comprometer ou anular as respostas fornecidas em um determinado momento é bastante ampla: se encerrássemos todas as perguntas onde isso poderia acontecer, o Stack Overflow seria um recurso muito mais pobre! Aqui, uma lista completa pode se tornar uma lista parcial, melhor do que nenhuma lista!
Bob Sammers

Respostas:

255

O LINQPad define dois métodos de extensão (em LINQPad.Extensions), a saber, Dump()e Disassemble().Dump()grava na janela de saída usando o formatador de saída do LINQPad e é sobrecarregado para permitir que você especifique um cabeçalho:

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

Você também pode especificar uma profundidade máxima de recursão para substituir o padrão de 5 níveis:

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

Desmontar () desmonta qualquer método para IL , retornando a saída em uma string:

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

Além desses dois métodos de extensão, existem alguns métodos estáticos úteis no LINQPad.Util. Eles estão documentados no preenchimento automático e incluem:

  • Cmd - executa um comando shell ou programa externo
  • CreateXhtmlWriter - cria um gravador de texto que usa o formatador Dump () do LINQPad
  • SqlOutputWriter - retorna o gravador de texto que grava na janela de saída SQL
  • GetMyQueries , GetSamples - retorna uma coleção de objetos que representam suas consultas / amostras salvas (por exemplo, execute uma pesquisa usando Editar | Pesquisar tudo)
  • Realçar - agrupa um objeto para que ele fique destacado em amarelo quando despejado
  • HorizontalRun - permite despejar uma série de objetos na mesma linha

O LINQPad também fornece a classe HyperLinq. Isso tem dois propósitos: o primeiro é exibir hiperlinks comuns:

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

Você pode combinar isso com Util.HorizontalRun:

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

Resultado:

Confira este site para obter respostas para perguntas sobre programação.

O segundo objetivo do HyperLinq é criar consultas 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();

Você também pode escrever seus próprios métodos de extensão no LINQPad. Vá para 'Minhas consultas' e clique na consulta chamada 'Minhas extensões'. Quaisquer tipos / métodos que definem aqui são acessíveis a todas as consultas:

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

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

Em 4.46 (.02), novas classes e métodos foram introduzidos :

  • DumpContainer (classe)
  • OnDemand (método de extensão)
  • Util.ProgressBar (classe)

Além disso, a classe Hyperlinq agora suporta um delegado Action que será chamado quando você clicar no link, permitindo que você reaja a ele no código e não apenas vincule a páginas da Web externas.

DumpContainer é uma classe que adiciona um bloco à janela de saída que pode ter seu conteúdo substituído.

NOTA! Lembre-se .Dump()a DumpContainersi mesma no local apropriado.

Usar:

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

OnDemand é um método de extensão que não gera o conteúdo de seu parâmetro na janela de saída, mas adiciona um link clicável que, quando clicado, substitui o link pelo .Dump() conteúdo ed do parâmetro. Isso é ótimo para estruturas de dados às vezes necessárias que são caras ou ocupam muito espaço.

NOTA! Lembre-se .Dump()dos resultados da chamada OnDemandno local apropriado.

Para usá-lo:

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

Util.ProgressBar é uma classe que pode mostrar uma barra de progresso gráfica dentro da janela de saída, que pode ser alterada à medida que o código avança.

NOTA! Lembre-se .Dump()do objeto Util.ProgressBar no local apropriado.

Para usá-lo:

var pb = new Util.ProgressBar("Analyzing data");
pb.Dump();
for (int index = 0; index <= 100; index++)
{
    pb.Percent = index;
    Thread.Sleep(100);
}
Joe Albahari
fonte
33
Nada melhor do que uma resposta do próprio autor!
John
1
Joe, na verdade, eu também queria criar protótipos para alguns gráficos e depois despejar um bitmap; seria ótimo com um método Show para esse tipo de trabalho, no qual você deseja alguma visualização, trabalhando com gráficos, imagem, etc. Possivelmente fornecendo visualizações precisas para alguns outros tipos no caminho.
Bent Rasmussen
... Na verdade, desde que você possa enviar gráficos para o painel de saída, podemos construir extensões para o resto.
Bent Rasmussen
3
A versão 4.26 permite injetar XHTML no fluxo de saída, chamando Util.RawHtml. Acesse www.linqpad.net/beta.aspx (ou aguarde alguns dias pela RTM).
Joe Albahari
1
Alex - para obter> 1 coisa em uma linha, use Util.HorizontalRun
Joe Albahari
131

Além do conhecido myQuery.Dump("Query result:"), outro recurso a ser mencionado é oUtil classe: contém muitos métodos bastante úteis (alguns deles que eu mencionei, mas existem muito mais).

Também interessante é que você pode modificar a maneira como Dump()funciona .

Por fim, mostrarei como você pode tornar as alterações permanentes (ou seja , inserir, atualizar, excluir consultas LINQ) usando SubmitChanges()ouSaveChanges() como também pode acessar o objeto de conexão interna do LinqPad.

E para finalizar , mostrarei como você pode criar gráficos 2D simples dentro do LinqPad ( linhas de desenho , bitmaps ou funções ).

Então, aqui está uma coleção de recursos internos do LinqPad (a partir de minha própria experiência com a ferramenta):


.Dump ()

(parâmetros disponíveis no LinqPad v5.03.08 e superior)

Todos os usuários do LinqPad conhecem e amam o .Dump() método de extensão, que consome e imprime (quase) tudo.

Mas você sabia que existem alguns parâmetros disponíveis? Dê uma olhada neste snippet de código:

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

Os primeiro exemplo imprime apenas variáveis ae ce esconde be d, o segundo exemplo faz o contrário (nota que especifica apenas 2 dos parâmetros disponíveis). As variáveis ye znão podem ser ocultadas individualmente, porque não estão no nível superior.

Os seguintes parâmetros estão disponíveis ( todos são opcionais ):

  • description [string] - fornece uma descrição para o objeto despejar
  • depth [int?] - limita a profundidade da inspeção recursiva dos objetos
  • toDataGrid [bool] - se true, a saída é formatada como um datagrid e não como RichText
  • exclude[string] - se você fornecer uma lista de variáveis ​​separadas por vírgula, elas serão excluídas da saída (no exemplo "a, c": be dsão mostradas aec estão escondidos)
  • exclude[string] com prefixo "+" - o prefixo inverte a lógica do parâmetro de exclusão. Isso significa que, se você fornecer uma lista de variáveis ​​separadas por vírgula, todas, exceto as especificadas, serão ocultadas (no exemplo "+ b, d": be dserão exibidas, todas as outras ocultas)
  • armazene propriedades incluídas e excluídas em uma variável (nova desde o LinqPad V5.09.04):
    var x=Util.ToExpando(obj, "a, c", "b, d"); x.Dump();
    a primeira string contém uma lista de propriedades a serem incluídas, a segunda string uma lista a ser excluída
  • expandir ao clicar: se você usar em .OnDemand("click me").Dump();vez de .Dump(), ele exibirá um link no qual você pode clicar para expandir. Útil se você deseja inspecionar valores, por exemplo, Util.OnDemand("Customer-ID: " + customerObject.ID.ToString(), ()=>customerObject, false).Dump();sempre mostrar o ID por padrão, mas revelar os detalhes customerObjectapenas se estiver interessado.

Tópicos mais avançados sobre o Dump podem ser encontrados aqui e ali .


Meio Ambiente

Esta não é uma extensão do LinqPad, mas sim uma classe .NET, mas como é útil, mencionarei de qualquer maneira. Você pode obter muitas informações úteis que podem ser usadas em seus scripts, como:

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

NB Para obter, Domain\UserNameeu usaria em System.Security.Principal.WindowsIdentity.GetCurrent().Name
vez de Environment.UserDomainName+@"\"+Environment.UserName.


Util.WriteCsv

( novo: disponível desde a versão LinqPad v4.45.05 (beta) )

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

Isso gravará o conteúdo da tabela Customersno arquivo CSV c:\temp\customers.csv. Você também pode encontrar um bom exemplo de como usar Util.WriteCsve exibir os dados CSV na janela de resultados do Linqpad aqui .

Dicas:

  • Para obter / criar um arquivo CSV que esteja no mesmo diretório da consulta, você pode usar:
    var csvFile=Util.CurrentQueryPath.Replace(".linq", ".csv");

  • Se a tabela for grande, use ObjectTrackingEnabled = false;antes de gravar o CSV para evitar armazená-lo na memória.

  • Se você deseja gerar uma tabela no formato XML, e não como arquivo separado por vírgula, é possível:

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

    Este exemplo retorna todos os elementos com o atributo attr1que contém o valor "a"de um arquivo XML que tem o mesmo nome que a consulta e está contido no mesmo caminho. Confira este link para mais exemplos de código.


Util.GetPassword

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

Isso recuperará a senha do gerenciador de senhas incorporado do LinqPad. Para criar e alterar a senha, abra o item de menu "Password Manager" no menu "File" de LinqPad. Se não houver senha salva ao executar o código C #, uma caixa de diálogo será exibida, solicitando a senha e você poderá criar e salvá-la em tempo real, marcando a caixa de seleção Salvar senha (no exemplo, a senha para "UserXY" seria salvo e, posteriormente, você poderá encontrar esta entrada no gerenciador de senhas ).

As vantagens são que você pode armazenar a senha nos LinqScripts criados com segurança, separadamente e criptografados no perfil de usuário do Windows (ele é armazenado em %localappdata%\LINQPad\Passwords como um arquivo). O LinqPad usa o Windows DPAPI para proteger a senha.

Além disso, a senha é armazenada centralmente; portanto, se você precisar alterá-la, poderá fazê-lo no menu e aplicar imediatamente a todos os scripts que você criou.

Notas:

  • Se você não quiser salvar a senha e apenas abrir um diálogo de senha, poderá usar o segundo parâmetro da seguinte maneira:
    var pwd = Util.GetPassword("UserXY", true);
    Isso desmarcará a caixa de seleção Salvar senha na caixa de diálogo de senha (no entanto, o usuário ainda poderá verificá-la e escolha salvar de qualquer maneira).

  • Se você precisar que a senha seja armazenada em a SecureString, poderá usar esta função auxiliar (nb: para obter o método de extensão .ToSecureString()usado, siga este link em Stackoverflow - ele também permite que você a converta novamente, se necessário):
    System.Security.SecureString GetPasswordSecure(string Name, bool noDefaultSave=true)
    {
      return Util.GetPassword(Name, noDefaultSave).ToSecureString();
    }


Util.Cmd

Este método funciona como um processador de comandos. Você pode chamar todos os comandos que você conhece no console do Windows.

Exemplo 1 - dir:

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

Isso produzirá o resultado do diretório sem a necessidade .Dumpdele. Armazená-lo em uma variável tem a vantagem de poder usar outras consultas do Linq. Por exemplo:

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

Isso irá despejar todos os arquivos com extensões de arquivo ".exe" ou ".dll" contidas em C:\windows\system32. A /sopção é usada para repetir todos os subdiretórios e/b é usado para o formato de saída bare. Observe que o segundo parâmetro do método Cmd é especificado para suprimir a saída do console para mostrar apenas o resultado filtrado usando o método Dump.

Você pode ver que isso é mais flexível do que os caracteres curinga que você possui, dirpois pode usar toda a flexibilidade do mecanismo de consulta do Linq.

Exemplo 2 - editor de texto:

Você pode abrir um arquivo no bloco de notas assim:

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

Util.Image

Exibe imagens de um URL. Exemplo:

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

Usar Util.ProgressBarpermite exibir uma barra de progresso. Você pode usar a seguinte classe auxiliar:

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;
        }
    }
}

Basta usá-lo como o exemplo a seguir mostra:

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

Como alternativa, você pode usar Util.Progresspara atualizar a barra de progresso integrada do LinqPads, por exemplo:

Util.Progress = 25; // 25 percent complete

A diferença é que ela não será exibida na janela de resultados e você não poderá atribuir uma mensagem a ela.


Util.RawHtml

Exibe HTML na janela de saída. Exemplo:

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

Hyperlinq, Util.HorizontalRun

Você pode usar esta função de exemplo

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

para mostrar hiperlinks na janela de resultados - ou qualquer ação como abrir seu editor favorito. Uso:

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

Observe que essa função sempre funciona, embora new Hyperlinq ("http://myURL", "Web site").Dump();não funcione para alguns tipos de URLs (especialmente se você precisar passar nomes de portas como ": 1234" como parte da URL).


Util.ReadLine

Lê a entrada do console. Exemplo:

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

Como sinônimo Util.ReadLine<string>(), você também pode usar Console.ReadLine().

Mas tem mais! É possível criar um analisador JSON simples com o seguinte trecho - bastante útil, por exemplo, se você deseja analisar e testar uma sequência JSON em tempo real. Salve o seguinte snippet como JSONAnalyzer.linq usando um editor de texto e abra-o no LinqPad (isto é para adicionar as referências facilmente em tempo real):

<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");
}

Agora você pode executá-lo e simplesmente colar uma string JSON da área de transferência no console - ela usará a Dumpfunção para exibi-la como um objeto bem - e você também receberá as mensagens de erro do analisador na tela para corrigir problemas. Muito útil para depurar AJAX.

JSON


Util.ClearResults

Se você precisar limpar a janela de resultados dentro do seu script, use:

Util.ClearResults();

Use-o na parte superior do seu script ou - se você estiver executando várias consultas em um script - deverá aguardar a entrada do usuário antes de apagar a tela (por exemplo, precedendo-a Util.ReadLine).


Custom .Dump () - ICustomMemberProvider

Também interessante é que você pode alterar a saída do .Dump()método. Simplesmente implemente a interface ICustomMemberProvider, por exemplo

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 você criar uma instância dessa classe, como

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

em seguida, ele irá imprimir única Hint, constMember1, constMember2, e myprop, mas não propriedade xyz:

Despejo do Linqpad


Exibindo um MessageBox ou InputBox no LinqPad

Se você precisar exibir uma caixa de mensagens, veja aqui como fazê-lo.

Por exemplo, você pode exibir um InputBox usando o seguinte código

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
    }
}

(não esqueça de pressionar F4 e adicionar Microsoft.VisualBasic.dll e seus espaços para nome para fazer isso funcionar)


Util.Run

( novo: disponível desde a versão LinqPad v4.52.1 (beta) )

Permite executar outro script LINQPad de dentro do seu script ou dentro do seu próprio programa .NET ou serviço do Windows (referenciando a versão do LINQPad4-AnyCPU do LINQPad.exe). Ele executa o script exatamente como a ferramenta de linha de comando lprun.exefaria.

Exemplos:

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

Este exemplo executa o script foo.linq, que contém o seguinte código de exemplo:

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");
}

Ele permite que você verifique se o script foi executado de dentro da GUI do LinqPad ou via lprun.exeou com Util.Run.

Nota: As seguintes variantes de chamada podem ser úteis:

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 para SQL

Se você estiver usando o LinqToSQL , poderá tornar as alterações permanentes (para operações de inserção / atualização / exclusão ). Como o contexto do banco de dados é implicitamente criado pelo LinqPad, é necessário chamar SubmitChanges()após cada alteração, como mostrado abaixo.

Exemplos para o banco de dados (LinqPad-) Northwind :

Inserir

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

Atualizar

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

Excluir

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

Nota: Para obter IDs válidos para os exemplos anteriores, você pode usar:

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

var pID = Products.Count()+1;

antes de invocá-los.


SaveChanges () - Estrutura da entidade

Se você estiver usando o Entity Framework , também poderá tornar as alterações permanentes (para operações de inserção / atualização / exclusão ). Como o contexto do banco de dados é implicitamente criado pelo LinqPad, é necessário chamar SaveChanges()após cada alteração, como mostrado abaixo.

Os exemplos são basicamente os mesmos de antes para o LinqToSQL , mas você precisa usá-lo SaveChanges()e, para inserir e excluir, os métodos também foram alterados.

Inserir

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

Atualizar

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

Excluir

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

Nota: Para obter IDs válidos para os exemplos anteriores, você pode usar:

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

var pID = Products.Count()+1;

antes de invocá-los.


this - contexto do banco de dados

No LinqPad , o contexto do banco de dados é aplicado automaticamente usando a caixa de combinação na parte superior e escolhendo o banco de dados correto para sua consulta. Mas, às vezes, é útil referenciá-lo explicitamente, por exemplo, se você copiar algum código do seu projeto fora do Visual Studio e colá-lo no LinqPad.

Seu snippet de código retirado do projeto Visual Studio provavelmente se parece com isso:

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

Agora o que fazer com dc? Obviamente, você pode remover cada ocorrência de dc.sua consulta, mas é muito mais fácil. Basta adicionar

var dc=this; // UserQuery

para o topo do seu snippet da seguinte forma:

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 o código funcionará instantaneamente!


this.Connection

Usando o LinqPad com OleDb, convertendo uma tabela de dados em um objeto Linq, as consultas SQL no Linq

O seguinte trecho de código ajuda você a usar o LinqPad com o OleDb. Adicione System.Data.OleDbdo System.Dataassembly às propriedades da consulta e cole o seguinte código em 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();

Agora adicione uma conexão SqlServer ao LinqPad e adicione o banco de dados Northwind para executar este exemplo.

NB: Se você deseja apenas obter o banco de dados e o servidor da conexão atualmente selecionada, pode usar este trecho de código:

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

Você pode até converter myDSpara o Linq, as respostas para a seguinte pergunta mostram como fazê-lo: Bons exemplos de como usar a palavra-chave dinâmica do .NET 4 com o Linq

Mais um exemplo: suponha que o seu DBA fornece uma consulta SQL e você deseja analisar os resultados no LinqPad - é claro no Linq, não no SQL. Então você pode fazer o seguinte:

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;
}

Neste exemplo, a consulta SELECT do DBA é apenas "lançada" no texto do comando, e os resultados são filtrados e ordenados por Cidade.
Obviamente, este é um exemplo simplificado, seu DBA provavelmente forneceria um script mais complexo, mas você está entendendo: Apenas adicione uma classe de resultado de suporte que contenha todos os campos da cláusula SELECT e você poderá usá-la diretamente .
Você pode até pegar o resultado de um procedimento armazenado dessa maneira e usá-lo no Linq. Como você pode ver, neste exemplo, não me importo com o tipo de dados e o uso dynamicpara expressá-lo.
Portanto, trata-se realmente de programação rápida para poder analisar dados rapidamente. Você não deve fazer isso em sua aplicação real por vários motivos (injeção de SQL, porque você pode usar EF desde o início, etc.).


PanelManager

Desenhar gráfico no LinqPad, parte 1

Para usar os exemplos a seguir, pressione F4e adicione System.Windows.dll, System.Windows.Forms.dll, WindowsFormsIntegration.dll, PresentationCore.dlle PresentationFramework.dllpara o seu programa LinqPad e também adicionar o namespace System.Windows.Shapes.

O primeiro exemplo simplesmente desenha uma linha:

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

O segundo exemplo mostra como você pode exibir gráficos no LinqPad usando o PanelManager. Normalmente, o LinqPad suporta apenas objetos Wpf. Este exemplo usa System.Windows.Forms.Integration.WindowsFormsHostpara Windows.Forms.PictureBoxdisponibilizar (foi inspirado por isso ):

// 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);
}

Isso criará o seguinte gráfico (os itens do painel "Gráfico" e "Imagem" são adicionados pelos exemplos acima):

Showing_Graphic_in_LinqPad

Se você deseja exibir as imagens do banco de dados Northwind, faça o seguinte:
Altere o nome do arquivo de imagem para "NorthwindPics.jpg" e adicione o seguinte código no início do método Main () do segundo exemplo :

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

Ele lerá o primeiro registro da tabela Funcionários e exibirá a figura.

Confira os links a seguir para saber mais:
Formas e desenho básico nos visualizadores personalizados do WPF
LinqPad

Nota: Você pode conseguir o mesmo sem o PanelManager, como mostra o exemplo a seguir, que vi aqui :

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

Está usando o .Dump()comando para exibi-lo. Você pode chamar image.Dump()várias vezes e ele acrescentará a imagem.


Windows Forms

Desenhar gráfico no LinqPad, parte 2

O exemplo a seguir, inspirado nesta publicação, mostra como implementar uma plotadora de funções simples no 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;
}

Ele está usando o recurso do LinqPad para exibir formulários do Windows no painel de resultados. Adicionar referências (imprensa ) : , , e adicionar todos os namespaces a partir destas assembléias.
Exemplo
F4
System.Drawing.dllSystem.Windows.Forms.dllSystem.Windows.Forms.DataVisualization.dll


Dicas adicionais / leitura adicional:

  • Deseja usar o LinqPad no Visual Studio ? Veja como você pode fazer isso .

  • Precisa ter o LinqPad como um "aplicativo portátil" ? Leia aqui como fazer isso.

  • O site de Joe para o LinqPad é sempre uma excelente fonte. Dentro do LinqPad, Help -> What's Newvocê fornece dicas sobre novas funções e métodos. O Fórum LinqPad também contém dicas úteis.

  • Também muito útil: este artigo sobre depuração do Linq (Pad).

  • Use lprun.exepara executar consultas LINQ em seus scripts em lote. Leia este artigo para mais detalhes. Por exemplo:
    echo Customers.Take(100) > script.txt
    lprun -lang=e -cxname=CompanyServer.CustomerDb script.txt
    Neste exemplo, a consulta é uma expressão LINQ simples. Obviamente, você também pode preparar consultas complexas usando -lang=programpara ativar o modo de programa.

  • Você pode escrever métodos de extensão e armazená-los na guia Minhas consultas, no lado esquerdo do LinqPad: O último item da árvore é chamado Minhas extensões ; clique duas vezes nele para abrir um arquivo onde é possível gravar extensões disponíveis para todas as suas consultas. Basta colocá-los na classe estática pública MyExtensionse usar o Main()método para incluir testes para suas extensões.

Matt
fonte
2
adore a dica sobre o Util.ReadLine <string> ("Enter some json"); Anteriormente, eu copiava em arquivo e depois lia a partir daí ... Eu realmente amo essa dica. Obrigado!
Loneshark99
2

O dump é um método de extensão global e o SubmitChanges vem do objeto DataContext, que é um objeto System.Data.Linq.DataContext.

LP adiciona apenas despejar e desmontar, tanto quanto eu sei. Embora eu recomendo abri-lo no Reflector para ver o que mais pode ser usado. Uma das coisas mais interessantes é o namespace LINQPad.Util, que possui alguns itens usados ​​internamente pelo LINQPad.

John
fonte
Nota: Nas versões mais recentes do LinqPad: Clique em .Dump()ou em qualquer outro método no editor de código-fonte, pressione F12 para "refletir". Agora isso está embutido na ferramenta!
Matt
1

Atingi o limite de texto StackOverflow na minha resposta anterior , mas ainda existem mais extensões interessantes no LinqPad. Um deles eu gostaria de mencionar:


Funções JavaScript (usando .Dump())

Desde a versão 5.42 beta do LinqPad, você pode incorporar funções JavaScript e chamá-las diretamente do seu código C #. Embora isso tenha algumas limitações (em comparação com o JSFiddle), é uma boa maneira de testar rapidamente algum código JavaScript no LinqPad.

Exemplo:

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");
}

Neste exemplo, uma função jsFoode um parâmetro é preparado e armazenado na variável literal. Então, ele é processado e chamado via .Dump().HtmlElement.InvokeScript(...), passando o parâmetro testparam.

A função JavaScript usa external.Log(...)para gerar texto nas janelas de saída do LinqPad ealert(...) exibir uma mensagem pop-up.

Você pode simplificar isso adicionando os seguintes métodos / classe de extensão:

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

Em seguida, você pode chamar o exemplo anterior da seguinte maneira:

    // 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");

Isso tem o mesmo efeito, mas é mais fácil de ler (se você pretende fazer mais JavaScript ;-)).

Outra opção, se você gosta de expressões Lambda e não gosta de especificar o nome da função como string sempre que a chama, é possível:

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

desde que você tenha adicionado a função auxiliar

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

para a classe ScriptExtension. Isso resolverá o nome da variável que você usou (aqui jsFoo), que passa a ser o mesmo nome da própria função JavaScript (observe como a expressão lambda é usada para resolver o nome da variável, isso não pode ser feito usando nameof(paramName)dentro da função).


.Dump () - atualizando uma mensagem em linha

Às vezes, é útil sobrescrever o texto que você despejou em vez de colocá-lo em uma nova linha, por exemplo, se você estiver executando uma consulta de longa execução e quiser mostrar seu progresso, etc (consulte também ProgressBar abaixo). Isso pode ser feito usando a DumpContainer, você pode usá-lo como mostrado na

Exemplo 1:

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

DumpContainerAnimation

Observe que, para alguns objetos mais complexos, você pode ter que usar em dc.UpdateContent(obj);vez de dc.Content=....

Exemplo 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

Mostrar o progresso também pode ser feito usando uma ProgressBar da seguinte maneira:

Exemplo:

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";
}

Isso é semelhante ao exemplo de despejo anterior, mas desta vez mostrando uma boa animação da barra de progresso.


Teste de unidade com LinqPad - xUnit

Você sabia que pode escrever testes de unidade no LinqPad? Por exemplo, você pode usar a estrutura xUnit. Está disponível através do suporte NUGET do LinqPad - via F4- no clique da caixa de diálogo Add NUGET..... Aqui está uma descrição passo a passo de como usar o xUnit com o LinqPad V5 ou V6.


Se descobrir mais, atualizarei esta resposta

Matt
fonte