Métodos LINQPad [extensión]

144

¿Alguien tiene una lista completa de métodos y métodos de extensión LINQPad, como

.Dump()

SubmitChanges()
Bent Rasmussen
fuente
1
Estoy votando para cerrar esta pregunta como fuera de tema porque LINQPad es una herramienta en constante cambio, tener una respuesta sólida y concreta y final sobre esta pregunta tendrá una vida muy corta. Propongo cerrarlo como fuera de tema para evitar promover preguntas similares para otras herramientas.
Lasse V. Karlsen
55
No es que tenga nada que decir sobre la votación, pero ciertamente no estoy de acuerdo con cerrar esta respuesta. Primero, solo mire los votos a favor de la pregunta, luego mire los votos a favor de los dos primeros comentarios. Segundo, ¿cómo pueden las respuestas de José ser menos que una respuesta final? él escribió la cosa. Finalmente, otras aplicaciones usan Stackoverflow para su documentación. Uso LinqPad para el desarrollo todo el tiempo, creando prototipos de consultas de C # y Linq, ejecutando SQL y haciendo tareas de DBA rápido, y docenas de otras cosas. Entonces, al menos para mí, las respuestas definitivamente son sobre el tema.
EoRaptor013
3
Volver a cerrar: he agregado más de una respuesta a preguntas anteriores en C # para proporcionar una técnica más moderna que se ha introducido en el lenguaje desde que se respondió la pregunta. En mi opinión, debemos esperar que la base de conocimiento que este sitio representa se modifique y actualice a medida que avanza la tecnología. La gama de temas en los que las actualizaciones futuras pueden comprometer o anular las respuestas dadas en un punto particular en el tiempo es bastante amplia: si cerramos todas las preguntas donde esto podría suceder, ¡Stack Overflow sería un recurso mucho más pobre! ¡Aquí, una lista completa puede convertirse en una lista parcial que es mejor que ninguna lista!
Bob Sammers

Respuestas:

255

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 ILdevuelve 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:

  • Cmd : ejecuta un comando de shell o un programa externo
  • CreateXhtmlWriter : crea un escritor de texto que utiliza el formateador Dump () de LINQPad
  • SqlOutputWriter : devuelve el escritor de texto que escribe en la ventana de salida de SQL
  • GetMyQueries , GetSamples : devuelve una colección de objetos que representan sus consultas / muestras guardadas (por ejemplo, ejecute una búsqueda usando Editar | Buscar todo)
  • Resaltar : ajusta un objeto para que se resalte en amarillo cuando se descarga
  • HorizontalRun : le permite volcar una serie de objetos en la misma línea

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:[email protected]", "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 :

  • DumpContainer (clase)
  • OnDemand (método de extensión)
  • Util.ProgressBar (clase)

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 DumpContainermisma en el lugar apropiado.

Usar:

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

OnDemandes 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 OnDemanden 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);
}
Joe Albahari
fuente
33
¡Nada mejor que una respuesta del propio autor!
John
1
Joe, en realidad también quería crear prototipos de algunos trabajos gráficos y luego quería deshacerme de un mapa de bits; sería genial con un método Show para este tipo de trabajo en el que desea alguna visualización, trabajando en Gráficos, Imagen, etc. Posiblemente proporcionando visualizaciones ordenadas para otros tipos en el futuro.
Doblado Rasmussen
... En realidad, siempre que pueda enviar gráficos al panel de salida, podemos construir extensiones para el resto nosotros mismos.
Doblado Rasmussen
3
La versión 4.26 beta le permite inyectar XHTML en la secuencia de salida, llamando a Util.RawHtml. Vaya a www.linqpad.net/beta.aspx (o espere unos días para RTM).
Joe Albahari
1
Alex: para obtener> 1 cosa en una línea, usa Util.HorizontalRun
Joe Albahari el
131

Además del conocido myQuery.Dump("Query result:"), otra característica a mencionar es la Utilclase: 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):


.Tugurio()

(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 ay cy cueros by d, el segundo ejemplo hace lo contrario (nota que especifica sólo 2 de los parámetros disponibles). Las variables yyz 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 volcar
  • depth [int?]: limita la profundidad de los objetos que se inspeccionan recursivamente
  • toDataGrid [bool]: si es verdadero, el resultado se formatea como una cuadrícula de datos en lugar de como RichText
  • exclude[cadena]: si proporciona una lista de variables separadas por comas, se excluirán de la salida (en el ejemplo "a, c": by dse muestran ay cse 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": by dse muestran, todas las demás están ocultas)
  • almacenar propiedades incluidas y excluidas en una variable (nuevo desde LinqPad V5.09.04):
    var x=Util.ToExpando(obj, "a, c", "b, d"); x.Dump();
    la primera cadena contiene una lista de propiedades para incluir, la segunda cadena una lista para excluir
  • expandir al hacer clic: si utiliza en .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 customerObjectsolo si está interesado.

Se pueden encontrar temas más avanzados sobre Dump aquí y allá .


Ambiente

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\UserNamelo usaría System.Security.Principal.WindowsIdentity.GetCurrent().Name
en lugar de Environment.UserDomainName+@"\"+Environment.UserName.


Util.WriteCsv

( 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 Customersen el archivo CSV c:\temp\customers.csv. También puede encontrar un buen ejemplo de cómo usar Util.WriteCsvy 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 attr1que 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.


Util.GetPassword

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


Util.Cmd

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 .Dumphacerlo. 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 /sinterruptor 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, dirya 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);

Util.Image

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

Util.ProgressBar, Util.Progress

El uso le Util.ProgressBarpermite 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.Progresspara 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.


Util.RawHtml

Muestra HTML en la ventana de salida. Ejemplo:

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

Hyperlinq, Util.HorizontalRun

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


Util.ReadLine

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

Ahora puede ejecutarlo y simplemente pegar una cadena JSON desde el portapapeles en la consola, usará la Dumpfunció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.

JSON


Util.ClearResults

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


Custom .Dump () - ICustomMemberProvider

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:

Volcado de Linqpad


Mostrar un cuadro de mensaje o cuadro de entrada en LinqPad

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)


Util.Run

( 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.exeharí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", "[email protected]", "[email protected]", "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.exeo 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

SubmitChanges () - Linq a SQL

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.


SaveChanges () - Entity Framework

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.


this - contexto de la base de datos

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!


this.Connection

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.OleDbdesde el System.Dataensamblaje 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 myDSa 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 dynamicpara 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.).


PanelManager

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.dlly PresentationFramework.dlla 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.WindowsFormsHostpara poner a Windows.Forms.PictureBoxdisposició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):

Mostrando_Gráficos_en_LinqPad

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.


Windows Forms

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.
Ejemplo
F4
System.Drawing.dllSystem.Windows.Forms.dllSystem.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 Newle 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.exepara 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=programpara 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 MyExtensionsy use el Main()método para incluir pruebas para sus extensiones.

Mate
fuente
2
me encanta el consejo sobre Util.ReadLine <string> ("Enter some json"); Anteriormente solía copiarlo en un archivo y luego leerlo desde allí ... Realmente me encanta este consejo. ¡Gracias!
loneshark99
2

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.

Juan
fuente
Nota: en las versiones más recientes de LinqPad: haga clic en .Dump()o en cualquier otro método en el editor de origen, presione F12 para "reflejar". ¡Esto ahora está integrado en la herramienta!
Matt
1

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:


Funciones de JavaScript (usando .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 jsFoocon 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).


.Dump () - actualizar un mensaje en línea

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

DumpContainerAnimation

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

Util.ProgressBar

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.


Prueba unitaria con LinqPad - xUnit

¿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

Mate
fuente