Alguém tem uma lista completa dos métodos e métodos de extensão LINQPad, como
.Dump()
SubmitChanges()
Alguém tem uma lista completa dos métodos e métodos de extensão LINQPad, como
.Dump()
SubmitChanges()
Respostas:
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:
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:user@domain.com", "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 :
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 DumpContainer
si 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 OnDemand
no 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);
}
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):
(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 a
e c
e esconde b
e d
, o segundo exemplo faz o contrário (nota que especifica apenas 2 dos parâmetros disponíveis). As variáveis y
e z
nã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 despejardepth
[int?] - limita a profundidade da inspeção recursiva dos objetostoDataGrid
[bool] - se true, a saída é formatada como um datagrid e não como RichTextexclude
[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": b
e d
são mostradas a
ec
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": b
e d
serão exibidas, todas as outras ocultas)var x=Util.ToExpando(obj, "a, c", "b, d"); x.Dump();
.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 customerObject
apenas se estiver interessado.Tópicos mais avançados sobre o Dump podem ser encontrados aqui e ali .
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\UserName
eu usaria em System.Security.Principal.WindowsIdentity.GetCurrent().Name
vez de Environment.UserDomainName+@"\"+Environment.UserName
.
( 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 Customers
no arquivo CSV c:\temp\customers.csv
. Você também pode encontrar um bom exemplo de como usar Util.WriteCsv
e 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 attr1
que 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.
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();
}
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 .Dump
dele. 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 /s
opçã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, dir
pois 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);
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();
Usar Util.ProgressBar
permite 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.Progress
para 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.
Exibe HTML na janela de saída. Exemplo:
Util.RawHtml (new XElement ("h1", "This is a big heading")).Dump();
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).
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><RuntimeDirectory>\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 Dump
funçã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.
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
).
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
:
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)
( 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.exe
faria.
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", "test@foo.com", "test@foo.com", "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.exe
ou 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
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.
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.
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!
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.OleDb
do System.Data
assembly à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 myDS
para 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 dynamic
para 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.).
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.dll
e PresentationFramework.dll
para 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.WindowsFormsHost
para Windows.Forms.PictureBox
disponibilizar (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):
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.
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.
F4
System.Drawing.dll
System.Windows.Forms.dll
System.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 New
você 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.exe
para 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=program
para 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 MyExtensions
e usar o Main()
método para incluir testes para suas extensões.
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.
.Dump()
ou em qualquer outro método no editor de código-fonte, pressione F12 para "refletir". Agora isso está embutido na ferramenta!
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:
.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 jsFoo
de 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).
À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.";
}
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!");
}
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.
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