¿Alguien tiene una lista completa de métodos y métodos de extensión LINQPad, como
.Dump()
SubmitChanges()
¿Alguien tiene una lista completa de métodos y métodos de extensión LINQPad, como
.Dump()
SubmitChanges()
Respuestas:
LINQPad define dos métodos de extensión (en LINQPad.Extensions), a saber, Dump()
y Disassemble()
. Dump()
escribe en la ventana de salida utilizando el formateador de salida de LINQPad y se sobrecarga para permitirle especificar un encabezado:
typeof (int).Assembly.Dump ();
typeof (int).Assembly.Dump ("mscorlib");
También puede especificar una profundidad de recursión máxima para anular el valor predeterminado de 5 niveles:
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 () desensambla cualquier método y IL
devuelve el resultado en una cadena:
typeof (Uri).GetMethod ("GetHashCode").Disassemble().Dump();
Además de esos dos métodos de extensión, hay algunos métodos estáticos útiles en LINQPad.Util. Estos están documentados en autocompletado e incluyen:
LINQPad también proporciona la clase HyperLinq. Esto tiene dos propósitos: el primero es mostrar hipervínculos ordinarios:
new Hyperlinq ("www.linqpad.net").Dump();
new Hyperlinq ("www.linqpad.net", "Web site").Dump();
new Hyperlinq ("mailto:user@domain.com", "Email").Dump();
Puedes combinar esto con Util.HorizontalRun
:
Util.HorizontalRun (true,
"Check out",
new Hyperlinq ("http://stackoverflow.com", "this site"),
"for answers to programming questions.").Dump();
Resultado:
Consulte este sitio para obtener respuestas a las preguntas de programación.
El segundo propósito de HyperLinq es generar consultas dinámicamente:
// 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();
También puede escribir sus propios métodos de extensión en LINQPad. Vaya a 'Mis consultas' y haga clic en la consulta llamada 'Mis extensiones'. Todos los tipos / métodos que definen aquí son accesibles para todas las 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);
}
}
En 4.46 (.02) se han introducido nuevas clases y métodos :
Además, la clase Hyperlinq ahora admite un delegado de Action que se llamará cuando haga clic en el enlace, lo que le permite reaccionar a él en el código y no solo vincular a páginas web externas.
DumpContainer
es una clase que agrega un bloque en la ventana de salida que puede reemplazar su contenido.
¡NOTA! Recuerde .Dump()
la DumpContainer
misma en el lugar apropiado.
Usar:
var dc = new DumpContainer();
dc.Content = "Test";
// further down in the code
dc.Content = "Another test";
OnDemand
es un método de extensión que no generará el contenido de su parámetro en la ventana de salida, sino que agregará un enlace en el que se puede hacer clic, que al hacer clic reemplazará el enlace con el .Dump()
contenido ed del parámetro. Esto es ideal para estructuras de datos que a veces se necesitan, que son costosas o ocupan mucho espacio.
¡NOTA! Recuerde .Dump()
los resultados de llamar OnDemand
en el lugar apropiado.
Para usarlo:
Customers.OnDemand("Customers").Dump(); // description is optional
Util.ProgressBar
es una clase que puede mostrar una barra de progreso gráfica dentro de la ventana de salida, que se puede cambiar a medida que avanza el código.
¡NOTA! Recuerde .Dump()
el objeto Util.ProgressBar en el lugar apropiado.
Para usarlo:
var pb = new Util.ProgressBar("Analyzing data");
pb.Dump();
for (int index = 0; index <= 100; index++)
{
pb.Percent = index;
Thread.Sleep(100);
}
Además del conocido myQuery.Dump("Query result:")
, otra característica a mencionar es la Util
clase: contiene muchos métodos bastante útiles (algunos de los cuales he mencionado, pero hay muchos más).
También es interesante que pueda modificar la forma en que Dump()
funciona .
Finalmente te mostraré cómo puedes hacer cambios permanentes (es decir , insertar, actualizar, eliminar consultas LINQ) usando SubmitChanges()
o SaveChanges()
cómo puede acceder al objeto de conexión interna de LinqPad.
Y para resumir, te mostraré cómo puedes crear simples gráficos 2D dentro de LinqPad (dibujar líneas, mapas de bits o funciones ).
Entonces, aquí hay una colección de características integradas de LinqPad (desde mi propia experiencia con la herramienta):
(parámetros disponibles en LinqPad v5.03.08 y superior)
Todos los usuarios de LinqPad conocen y aman el .Dump()
método de extensión, que consume e imprime (casi) todo.
¿Pero sabías que hay un par de parámetros disponibles? Eche un vistazo a este fragmento 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
Los primero ejemplos de impresiones únicas variables a
y c
y cueros b
y d
, el segundo ejemplo hace lo contrario (nota que especifica sólo 2 de los parámetros disponibles). Las variables y
yz
no se pueden ocultar individualmente, porque no están en el nivel superior.
Los siguientes parámetros están disponibles ( todos son opcionales ):
description
[cadena]: proporciona una descripción del objeto para volcardepth
[int?]: limita la profundidad de los objetos que se inspeccionan recursivamentetoDataGrid
[bool]: si es verdadero, el resultado se formatea como una cuadrícula de datos en lugar de como RichTextexclude
[cadena]: si proporciona una lista de variables separadas por comas, se excluirán de la salida (en el ejemplo "a, c": b
y d
se muestran a
y c
se ocultan)exclude
[cadena] con el prefijo "+": el prefijo invierte la lógica del parámetro de exclusión. Esto significa que si proporciona una lista de variables separadas por comas, todas excepto las especificadas están ocultas (en el ejemplo "+ b, d": b
y d
se muestran, todas las demás están ocultas)var x=Util.ToExpando(obj, "a, c", "b, d"); x.Dump();
.OnDemand("click me").Dump();
lugar de .Dump()
, mostrará un enlace en el que puede hacer clic para expandir. Útil si desea inspeccionar valores, por ejemplo, Util.OnDemand("Customer-ID: " + customerObject.ID.ToString(), ()=>customerObject, false).Dump();
para mostrar siempre la ID por defecto pero revelar los detalles customerObject
solo si está interesado.Se pueden encontrar temas más avanzados sobre Dump aquí y allá .
Esta no es una extensión de LinqPad, sino una clase .NET, pero como es útil, lo mencionaré de todos modos. Puede obtener mucha información útil que puede usar en sus scripts, como:
Environment.UserDomainName.Dump();
Environment.MachineName.Dump();
Environment.UserName.Dump();
Environment.CurrentDirectory.Dump();
Environment.SystemDirectory.Dump();
Nota: Para obtener Domain\UserName
lo usaría System.Security.Principal.WindowsIdentity.GetCurrent().Name
en lugar de Environment.UserDomainName+@"\"+Environment.UserName
.
( nuevo: disponible desde la versión de LinqPad v4.45.05 (beta) )
Util.WriteCsv (Customers, @"c:\temp\customers.csv");
Esto escribirá el contenido de la tabla Customers
en el archivo CSV c:\temp\customers.csv
. También puede encontrar un buen ejemplo de cómo usar Util.WriteCsv
y luego mostrar los datos CSV en la ventana de resultados de Linqpad aquí .
Consejos:
Para obtener / crear un archivo CSV que esté en el mismo directorio que la consulta, puede usar:
var csvFile=Util.CurrentQueryPath.Replace(".linq", ".csv");
Si la tabla es grande, úsela ObjectTrackingEnabled = false;
antes de escribir el CSV para evitar el almacenamiento en caché en la memoria.
Si desea generar una tabla en formato XML en lugar de un archivo separado por comas, puede hacerlo como:
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 ejemplo devuelve todos los elementos que tienen el atributo attr1
que contiene el valor "a"
de un archivo XML que tiene el mismo nombre que la consulta y está contenido en la misma ruta. Consulte este enlace para obtener más ejemplos de código.
var pwd = Util.GetPassword("UserXY");
Esto recuperará la contraseña del administrador de contraseñas incorporado de LinqPad. Para crear y cambiar la contraseña, abrir la opción de menú "Gestor de contraseñas" en el menú "Archivo" de LINQPad. Si no se guarda una contraseña cuando ejecuta el código C #, se abrirá un cuadro de diálogo de contraseña que le pedirá la contraseña y usted tiene la opción de crearla y guardarla sobre la marcha marcando la casilla de verificación guardar contraseña (en el ejemplo, la contraseña para "UserXY" se guardaría, y más tarde puede encontrar esta entrada en el Administrador de contraseñas ).
Las ventajas son que puede almacenar la contraseña en los LinqScripts que crea de forma segura, por separado y encriptada en el perfil de usuario de Windows (se almacena %localappdata%\LINQPad\Passwords
como un archivo). LinqPad usa Windows DPAPI para proteger la contraseña.
Además, la contraseña se almacena de forma centralizada, por lo que si necesita cambiarla, puede hacerlo en el menú e inmediatamente se aplica a todos los scripts que ha creado.
Notas:
Si no desea guardar la contraseña y solo aparece un cuadro de diálogo de contraseña, puede usar el segundo parámetro de la siguiente manera:
var pwd = Util.GetPassword("UserXY", true);
Esto desmarcará la casilla de verificación Guardar contraseña en el cuadro de diálogo de contraseña (sin embargo, el usuario aún puede marcarlo y elige guardar de todos modos).
Si necesita que la contraseña se almacene en a SecureString
, puede usar esta función auxiliar (nb: para .ToSecureString()
usar el método de extensión , siga este enlace en Stackoverflow ; también le permite volver a convertirlo si es necesario):
System.Security.SecureString GetPasswordSecure(string Name, bool noDefaultSave=true)
{
return Util.GetPassword(Name, noDefaultSave)
.ToSecureString();
}
Este método funciona como un procesador de comandos. Puede invocar todos los comandos que conoce desde la consola de Windows.
Ejemplo 1 - dir:
Util.Cmd(@"dir C:\");
Esto generará el resultado del directorio sin la necesidad de .Dump
hacerlo. Almacenarlo en una variable tiene la ventaja de que puede usar más consultas de Linq en él. Por ejemplo:
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();
Esto volcará todos los archivos con extensiones de archivo ".exe" o ".dll" contenidos en C:\windows\system32
. El /s
interruptor se usa para repetir todos los subdirectorios y/b
se usa para el formato de salida simple. Tenga en cuenta que el segundo parámetro del método Cmd se especifica para suprimir la salida de la consola para mostrar solo el resultado filtrado utilizando el método Dump.
Puede ver que esto es más flexible que los comodines que tiene, dir
ya que puede usar toda la flexibilidad del motor de consultas de Linq.
Ejemplo 2 - editor de texto:
Puede abrir un archivo en el Bloc de notas de esta manera:
var filePath=@"C:\HelloWorld.txt";
Util.Cmd(@"%systemroot%\system32\notepad.exe", filePath);
Muestra imágenes de una URL. Ejemplo:
var url = "http://chart.apis.google.com/chart?cht=p3&chd=s:Uf9a&chs=350x140&chl=January|February|March|April";
Util.Image(url).Dump();
El uso le Util.ProgressBar
permite mostrar una barra de progreso. Puede usar la siguiente clase 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;
}
}
}
Simplemente utilícelo como se muestra en el siguiente ejemplo:
void Main()
{
var pb1= new ProgressBar();
Thread.Sleep(50);
pb1.Update(50, "Doing something"); Thread.Sleep(550);
pb1.Update(100); Thread.Sleep(50);
}
Alternativamente, puede usar Util.Progress
para actualizar la barra de progreso integrada de LinqPads, por ejemplo:
Util.Progress = 25; // 25 percent complete
La diferencia es que no se mostrará en la ventana de resultados y no puede asignarle un mensaje.
Muestra HTML en la ventana de salida. Ejemplo:
Util.RawHtml (new XElement ("h1", "This is a big heading")).Dump();
Puedes usar esta función de ejemplo
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 hipervínculos en la ventana de resultados, o cualquier acción como abrir su editor favorito. Uso:
ShowUrl("http://stackoverflow.com", "Check out StackOverflow");
Tenga en cuenta que esta función siempre funciona, mientras new Hyperlinq ("http://myURL", "Web site").Dump();
que no funciona para algún tipo de URL (especialmente, si tiene que pasar nombres de puerto como ": 1234" como parte de la URL).
Lee la entrada de la consola. Ejemplo:
int age = Util.ReadLine<int> ("Enter your age");
Como sinónimo de Util.ReadLine<string>()
, puedes usar Console.ReadLine()
también.
¡Pero hay más! Puede crear un analizador JSON simple con el siguiente fragmento: bastante útil, por ejemplo, si desea analizar y probar una cadena JSON sobre la marcha. Guarde el siguiente fragmento como JSONAnalyzer.linq usando un editor de texto y luego ábralo en LinqPad (esto es para agregar las referencias fácilmente sobre la marcha):
<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");
}
Ahora puede ejecutarlo y simplemente pegar una cadena JSON desde el portapapeles en la consola, usará la Dump
función para mostrarlo como un objeto agradable, y también recibirá los mensajes de error del analizador en la pantalla para solucionar problemas. Muy útil para depurar AJAX.
Si necesita borrar la ventana de resultados dentro de su script, use:
Util.ClearResults();
Úselo en la parte superior de su secuencia de comandos o, si está ejecutando múltiples consultas en una secuencia de comandos, debe esperar la entrada del usuario antes de borrar la pantalla (por ejemplo, precediéndola con Util.ReadLine
).
También es interesante, que puede cambiar la salida del .Dump()
método. Simplemente implemente la interfaz ICustomMemberProvider
, p. Ej.
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
}
Si crea una instancia de esta clase, como
var obj1 = new test();
obj1.Dump("Test");
entonces se dará salida única Hint
, constMember1
, constMember2
, y myprop
, pero no la propiedad xyz
:
Si necesita mostrar un cuadro de mensaje, mire aquí cómo hacerlo.
Por ejemplo, puede mostrar un InputBox utilizando el siguiente 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
}
}
(no olvide presionar F4 y agregar Microsoft.VisualBasic.dll y sus espacios de nombres para que esto funcione)
( nuevo: disponible desde LinqPad versión v4.52.1 (beta) )
Le permite ejecutar otro script LINQPad desde su script o desde su propio programa .NET o servicio de Windows (haciendo referencia a la versión LINQPad4-AnyCPU de LINQPad.exe
). Ejecuta el script tal como lo lprun.exe
haría la herramienta de línea de comando .
Ejemplos:
const string path=@"C:\myScripts\LinqPad\";
var dummy=new LINQPad.QueryResultFormat(); // needed to call Util.Run
Util.Run(path+"foo.linq", dummy);
Este ejemplo ejecuta el script foo.linq
, que contiene el siguiente código de muestra:
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");
}
Le permite verificar si el script se ejecutó desde el interior de la GUI de LinqPad o mediante lprun.exe
o con Util.Run
.
Nota: Las siguientes variantes de invocación pueden ser útiles:
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
Si está utilizando LinqToSQL , es posible que desee realizar cambios permanentes (para operaciones de inserción / actualización / eliminación ). Como el contexto de la base de datos está implícitamente hecho por LinqPad, debe llamar SubmitChanges()
después de cada cambio como se muestra a continuación.
Ejemplos para la base de datos (LinqPad-) Northwind :
Insertar
var newP = new Products() { ProductID=pID, CategoryID=cID,
ProductName="Salmon#"+pID.ToString() };
Products.InsertOnSubmit(newP);
SubmitChanges();
Actualizar
var prod=(from p in Products
where p.ProductName.Contains("Salmon")
select p).FirstOrDefault();
prod.ProductName="Trout#"+prod.ProductID.ToString();
SubmitChanges();
Eliminar
var itemsToDelete=Products.Where(p=> p.ProductName.Contains("Salmon") ||
p.ProductName.Contains("Trout"));
foreach(var item in itemsToDelete) { Products.DeleteOnSubmit(item); }
SubmitChanges();
Nota: Para obtener ID válidos para los ejemplos anteriores, puede usar:
var cID = (from c in Categories
where c.CategoryName.Contains("Seafood")
select c).FirstOrDefault().CategoryID;
var pID = Products.Count()+1;
antes de invocarlos.
Si está utilizando Entity Framework , es posible que también desee realizar cambios permanentes (para operaciones de inserción / actualización / eliminación ). Dado que LinqPad crea implícitamente el contexto de la base de datos, debe llamar SaveChanges()
después de cada cambio como se muestra a continuación.
Los ejemplos son básicamente los mismos que antes para LinqToSQL , pero debe usarSaveChanges()
, y para insertar y eliminar los métodos también han cambiado.
Insertar
var newP = new Products() { ProductID=pID, CategoryID=cID,
ProductName="Salmon#"+pID.ToString() };
Products.Add(newP);
SaveChanges();
Actualizar
var prod=(from p in Products
where p.ProductName.Contains("Salmon")
select p).FirstOrDefault();
prod.ProductName="Trout#"+prod.ProductID.ToString();
SaveChanges();
Eliminar
var itemsToDelete=Products.Where(p=> p.ProductName.Contains("Salmon") ||
p.ProductName.Contains("Trout"));
foreach(var item in itemsToDelete) { Products.Remove(item); }
SaveChanges();
Nota: Para obtener ID válidos para los ejemplos anteriores, puede usar:
var cID = (from c in Categories
where c.CategoryName.Contains("Seafood")
select c).FirstOrDefault().CategoryID;
var pID = Products.Count()+1;
antes de invocarlos.
En LinqPad , el contexto de la base de datos se aplica automáticamente mediante el cuadro combinado en la parte superior y seleccionando la base de datos adecuada para su consulta. Pero a veces, es útil hacer referencia explícita a él, por ejemplo, si copia algún código de su proyecto fuera de Visual Studio y lo pega en LinqPad.
Es muy probable que su fragmento de código tomado del proyecto de Visual Studio tenga este aspecto:
var prod=(from p in dc.Products
where p.ProductName.Contains("Salmon")
select p).FirstOrDefault();
prod.ProductName="Trout#"+prod.ProductID.ToString();
dc.SaveChanges();
¿Ahora qué hacer con dc
? Por supuesto, puede eliminar cada aparición dc.
en su consulta, pero es mucho más fácil. Solo agrega
var dc=this; // UserQuery
en la parte superior de tu fragmento así:
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();
}
¡y el código funcionará al instante!
Usando LinqPad con OleDb, convirtiendo una tabla de datos a un objeto Linq, consultas SQL en Linq
El siguiente fragmento de código le ayuda a usar LinqPad con OleDb. Agregue System.Data.OleDb
desde el System.Data
ensamblaje a las propiedades de consulta, luego pegue el siguiente código en 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();
Ahora agregue una conexión SqlServer a LinqPad y agregue la base de datos Northwind para ejecutar este ejemplo.
NB: si solo desea obtener la base de datos y el servidor de la conexión seleccionada actualmente, puede usar este fragmento 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();
}
Incluso puede convertir myDS
a Linq, las respuestas a la siguiente pregunta muestran cómo hacerlo: buenos ejemplos de uso de .NET 4 palabra clave dinámica con Linq
Un ejemplo más: suponga que su DBA le proporciona una consulta SQL y desea analizar los resultados en LinqPad, por supuesto, en Linq, no en SQL. Entonces puedes hacer lo siguiente:
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;
}
En este ejemplo, la consulta SELECT del DBA simplemente se "arroja" al texto del comando y City filtra y ordena los resultados.
Por supuesto, este es un ejemplo simplificado, su DBA probablemente le dará un script más complejo, pero se está haciendo una idea: simplemente agregue una clase de resultado de soporte que contenga todos los campos de la cláusula SELECT y luego puede usarla directamente .
Incluso puede tomar el resultado de un procedimiento almacenado de esta manera y usarlo en Linq. Como puede ver, en este ejemplo no me importa el tipo de datos y lo uso dynamic
para expresarlo.
Así que se trata realmente de una programación rápida para poder analizar datos rápidamente. No debe hacer esto en su aplicación real por varias razones (inyección SQL, porque puede usar EF desde el principio, etc.).
Dibujar gráfico en LinqPad, parte 1
Para utilizar los ejemplos a continuación, presione F4y añadir System.Windows.dll
, System.Windows.Forms.dll
, WindowsFormsIntegration.dll
, PresentationCore.dll
y PresentationFramework.dll
a su programa LINQPad y también agregar el espacio de nombres System.Windows.Shapes
.
El primer ejemplo simplemente dibuja una línea:
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");
El segundo ejemplo muestra cómo puede mostrar gráficos en LinqPad utilizando el PanelManager. Normalmente, LinqPad solo admite objetos Wpf. Este ejemplo se utiliza System.Windows.Forms.Integration.WindowsFormsHost
para poner a Windows.Forms.PictureBox
disposición (se inspiró en esto ):
// 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);
}
Esto creará el siguiente gráfico (los elementos anteriores del panel "Gráfico" e "Imagen" se agregan):
Si desea mostrar las imágenes de la base de datos Northwind, puede hacer lo siguiente:
Cambiar el nombre del archivo de imagen a "NorthwindPics.jpg", luego agregar el siguiente código al comienzo del método Main () del segundo ejemplo :
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();
}
Leerá el primer registro de la tabla Empleados y mostrará la imagen.
Consulte los siguientes enlaces para obtener más información:
Formas y dibujos básicos en visualizadores personalizados WPF
LinqPad
Nota: También puede lograr lo mismo sin el PanelManager, como muestra el siguiente ejemplo, que vi aquí :
// 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á utilizando el .Dump()
comando para mostrarlo. Puede invocar image.Dump()
varias veces y adjuntará la imagen.
Dibujar gráfico en LinqPad, parte 2
El siguiente ejemplo, inspirado en esta publicación, muestra cómo implementar un trazador de funciones simple en 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;
}
Está utilizando la capacidad de LinqPad para mostrar formularios de Windows en el panel de resultados.
Añadir referencias (prensa ) : , , y añadir todos los espacios de nombres de estas asambleas.
F4
System.Drawing.dll
System.Windows.Forms.dll
System.Windows.Forms.DataVisualization.dll
Consejos adicionales / lecturas adicionales:
¿Quieres usar LinqPad en Visual Studio ? Así es como puedes hacer eso .
¿Necesita tener LinqPad como una "aplicación portátil" ? Lee aquí cómo hacerlo.
El sitio web de Joe para LinqPad es siempre una excelente fuente. Dentro de LinqPad, Help -> What's New
le da pistas sobre nuevas funciones y métodos. El foro LinqPad también contiene consejos útiles.
También muy útil: este artículo sobre la depuración de Linq (Pad).
Úselo lprun.exe
para ejecutar consultas LINQ en sus scripts por lotes. Lea este artículo para más detalles. Por ejemplo:
echo Customers.Take(100) > script.txt
lprun -lang=e -cxname=CompanyServer.CustomerDb script.txt
en este ejemplo, la consulta es una expresión LINQ simple. Por supuesto, también puede preparar consultas complejas utilizando -lang=program
para activar el modo de programa.
Puede escribir métodos de extensión y almacenarlos en la pestaña Mis consultas en el lado izquierdo de LinqPad: el último elemento del árbol se llama Mis extensiones ; haga doble clic en él para abrir un archivo donde pueda escribir extensiones que estén disponibles para todas sus consultas. Simplemente colóquelos en la clase estática pública MyExtensions
y use el Main()
método para incluir pruebas para sus extensiones.
Dump es un método de extensión global y SubmitChanges proviene del objeto DataContext que es un objeto System.Data.Linq.DataContext.
LP solo agrega Dump and Disassemble hasta donde yo sé. Aunque recomiendo encarecidamente abrirlo en Reflector para ver qué más hay allí que se pueda usar. Una de las cosas más interesantes es el espacio de nombres LINQPad.Util que tiene algunas ventajas utilizadas por LINQPad internamente.
.Dump()
o en cualquier otro método en el editor de origen, presione F12 para "reflejar". ¡Esto ahora está integrado en la herramienta!
Alcancé el límite de texto de StackOverflow en mi respuesta anterior , pero todavía hay extensiones más interesantes en LinqPad. Una de ellas me gustaría mencionar:
.Dump()
)Desde la versión 5.42 beta de LinqPad, puede incorporar funciones de JavaScript y llamarlas directamente desde su código C #. Aunque esto tiene algunas limitaciones (en comparación con JSFiddle), es una buena manera de probar rápidamente algún código JavaScript en LinqPad.
Ejemplo:
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");
}
En este ejemplo, una función jsFoo
con un parámetro se prepara y almacena en la variable literal
. Luego, se representa y se llama vía .Dump().HtmlElement.InvokeScript(...)
, pasando el parámetro testparam
.
La función de JavaScript se utiliza external.Log(...)
para generar texto en las ventanas de salida de LinqPad, yalert(...)
para mostrar un mensaje emergente.
Puede simplificar esto agregando la siguiente clase / métodos de extensión:
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);
}
}
Entonces puede llamar al ejemplo anterior de la siguiente manera:
// 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");
Eso tiene el mismo efecto, pero es más fácil de leer (si tiene la intención de hacer más JavaScript ;-)).
Otra opción, si le gustan las expresiones Lambda y no le gusta especificar el nombre de la función como cadena cada vez que lo llama, puede hacer lo siguiente:
var jsFoo = ScriptExtension.CreateJavaScript(
@"function jsFoo(x) { ... }");
ScriptExtension.RunJavaScript(() => jsFoo, "testparam");
siempre que haya agregado la función 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);
}
a la clase ScriptExtension
. Esto resolverá el nombre de la variable que usó (aquí jsFoo
) que resulta ser el mismo nombre que la función de JavaScript en sí (tenga en cuenta cómo se usa la expresión lambda para resolver el nombre de la variable, esto no se puede hacer usando nameof(paramName)
dentro de la función).
A veces es útil sobrescribir el texto que volcó en lugar de ponerlo en una nueva línea, por ejemplo, si está realizando una consulta de larga duración y desea mostrar su progreso, etc. (consulte también ProgressBar a continuación). Esto se puede hacer usando un DumpContainer
, puede usarlo como se muestra en el
Ejemplo 1:
void Main()
{
var dc = new DumpContainer("Doing something ... ").Dump("Some Action");
System.Threading.Thread.Sleep(3000); // wait 3 seconds
dc.Content += "Done.";
}
Tenga en cuenta que para algunos objetos más complejos, es posible que tenga que usar en dc.UpdateContent(obj);
lugar de dc.Content=...
.
Ejemplo 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!");
}
También se puede mostrar el progreso utilizando una barra de progreso de la siguiente manera:
Ejemplo:
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";
}
Esto es similar al ejemplo de volcado anterior, pero esta vez muestra una buena animación de barra de progreso.
¿Sabía que puede escribir pruebas unitarias en LinqPad? Por ejemplo, puede usar el marco xUnit. Está disponible a través del soporte NUGET de LinqPad, a través F4del diálogo, haga clic en Add NUGET..... Aquí hay una descripción paso a paso de cómo usar xUnit con LinqPad V5 o V6.
Si descubro más, actualizaré esta respuesta