Quelqu'un a-t-il une liste complète des méthodes et méthodes d'extension LINQPad, telles que
.Dump()
SubmitChanges()
Quelqu'un a-t-il une liste complète des méthodes et méthodes d'extension LINQPad, telles que
.Dump()
SubmitChanges()
Réponses:
LINQPad définit deux méthodes d'extension (dans LINQPad.Extensions), à savoir Dump()
et Disassemble()
. Dump()
écrit dans la fenêtre de sortie à l'aide du formateur de sortie de LINQPad et est surchargé pour vous permettre de spécifier un en-tête:
typeof (int).Assembly.Dump ();
typeof (int).Assembly.Dump ("mscorlib");
Vous pouvez également spécifier une profondeur de récursivité maximale pour remplacer la valeur par défaut de 5 niveaux:
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 () désassemble toute méthode en IL
, retournant la sortie dans une chaîne:
typeof (Uri).GetMethod ("GetHashCode").Disassemble().Dump();
En plus de ces deux méthodes d'extension, il existe des méthodes statiques utiles dans LINQPad.Util. Ceux-ci sont documentés dans la saisie semi-automatique et comprennent:
LINQPad fournit également la classe HyperLinq. Cela a deux objectifs: le premier est d'afficher des hyperliens ordinaires:
new Hyperlinq ("www.linqpad.net").Dump();
new Hyperlinq ("www.linqpad.net", "Web site").Dump();
new Hyperlinq ("mailto:user@domain.com", "Email").Dump();
Vous pouvez combiner cela avec Util.HorizontalRun
:
Util.HorizontalRun (true,
"Check out",
new Hyperlinq ("http://stackoverflow.com", "this site"),
"for answers to programming questions.").Dump();
Résultat:
Consultez ce site pour obtenir des réponses aux questions de programmation.
Le deuxième objectif d'HyperLinq est de créer dynamiquement des requêtes:
// 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();
Vous pouvez également écrire vos propres méthodes d'extension dans LINQPad. Allez dans «Mes requêtes» et cliquez sur la requête intitulée «Mes extensions». Tous les types / méthodes définis ici sont accessibles à toutes les requêtes:
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), de nouvelles classes et méthodes ont été introduites :
En outre, la classe Hyperlinq prend désormais en charge un délégué Action qui sera appelé lorsque vous cliquez sur le lien, ce qui vous permet de réagir dans le code et pas seulement de créer un lien vers des pages Web externes.
DumpContainer
est une classe qui ajoute un bloc dans la fenêtre de sortie dont le contenu peut être remplacé.
REMARQUE! N'oubliez pas de vous .Dump()
- DumpContainer
même à l'endroit approprié.
Utiliser:
var dc = new DumpContainer();
dc.Content = "Test";
// further down in the code
dc.Content = "Another test";
OnDemand
est une méthode d'extension qui ne sortira pas le contenu de son paramètre dans la fenêtre de sortie, mais ajoutera à la place un lien cliquable qui, une fois cliqué, remplacera le lien par le .Dump()
contenu ed du paramètre. C'est parfait pour les structures de données parfois nécessaires qui sont coûteuses ou prennent beaucoup de place.
REMARQUE! N'oubliez pas .Dump()
les résultats de l'appel OnDemand
à l'endroit approprié.
Pour l'utiliser:
Customers.OnDemand("Customers").Dump(); // description is optional
Util.ProgressBar
est une classe qui peut afficher une barre de progression graphique dans la fenêtre de sortie, qui peut être modifiée au fur et à mesure que le code avance.
REMARQUE! N'oubliez pas de .Dump()
placer l'objet Util.ProgressBar à l'endroit approprié.
Pour l'utiliser:
var pb = new Util.ProgressBar("Analyzing data");
pb.Dump();
for (int index = 0; index <= 100; index++)
{
pb.Percent = index;
Thread.Sleep(100);
}
Outre la bien connue myQuery.Dump("Query result:")
, une autre caractéristique à mentionner est la Util
classe: elle contient de nombreuses méthodes assez pratiques (dont certaines que j'ai mentionnées, mais il y en a beaucoup plus).
Il est également intéressant de pouvoir modifier le Dump()
fonctionnement .
Enfin, je vais vous montrer comment vous pouvez rendre les modifications permanentes (c'est-à-dire insérer, mettre à jour, supprimer des requêtes LINQ) en utilisant SubmitChanges()
ou SaveChanges()
ainsi que comment vous pouvez accéder à l'objet de connexion interne de LinqPad.
Et pour arrondir, je vais vous montrer comment créer un graphique 2D simple à l' intérieur de LinqPad (dessin de lignes, de bitmaps ou de fonctions ).
Alors, voici une collection de fonctionnalités LinqPad intégrées (de ma propre expérience avec l'outil):
(paramètres disponibles dans LinqPad v5.03.08 et supérieur)
Tous les utilisateurs de LinqPad connaissent et aiment la .Dump()
méthode d'extension, qui consomme et imprime (presque) tout.
Mais saviez-vous qu'il existe quelques paramètres disponibles? Jetez un œil à cet extrait de code:
var obj=new { a="Hello", b=5, c="World", d=new { y=5, z=10 } };
obj.Dump(description: "1st example", depth: 5, toDataGrid: false, exclude: "b,d");
obj.Dump("2nd example", exclude: "a,c");
obj.Dump("2nd example", exclude: "+b,d"); // new in V5.06.06 beta
Le 1er exemple n'imprime que les variables a
et c
et masque b
et d
, le 2ème exemple fait l'inverse (notez qu'il ne spécifie que 2 des paramètres disponibles). Les variables y
et z
ne peuvent pas être masquées individuellement, car elles ne sont pas au niveau supérieur.
Les paramètres suivants sont disponibles ( tous sont facultatifs ):
description
[string] - fournit une description de l'objet à viderdepth
[int?] - limite la profondeur à laquelle les objets sont inspectés récursivementtoDataGrid
[booléen] - si true, la sortie est formatée comme une grille de données plutôt que comme RichTextexclude
[chaîne] - si vous fournissez une liste de variables séparées par des virgules, elles seront exclues de la sortie (dans l'exemple "a, c": b
et d
sont affichées, a
et c
sont masquées)exclude
[chaîne] avec le préfixe "+" - le préfixe inverse la logique du paramètre d'exclusion. Cela signifie que si vous fournissez une liste de variables séparées par des virgules, toutes sauf celles spécifiées sont masquées (dans l'exemple "+ b, d": b
et d
sont affichées, toutes les autres masquées)var x=Util.ToExpando(obj, "a, c", "b, d"); x.Dump();
.OnDemand("click me").Dump();
place de .Dump()
, il affichera un lien sur lequel vous pouvez cliquer pour développer Utile si vous voulez inspecter les valeurs, par exemple Util.OnDemand("Customer-ID: " + customerObject.ID.ToString(), ()=>customerObject, false).Dump();
pour toujours afficher l'ID par défaut mais révéler les détails de customerObject
seulement si cela vous intéresse.Des sujets plus avancés sur Dump peuvent être trouvés ici et là .
Ce n'est pas une extension LinqPad, mais plutôt une classe .NET, mais comme c'est utile, je le mentionnerai quand même. Vous pouvez obtenir de nombreuses informations utiles que vous pouvez utiliser dans vos scripts, telles que:
Environment.UserDomainName.Dump();
Environment.MachineName.Dump();
Environment.UserName.Dump();
Environment.CurrentDirectory.Dump();
Environment.SystemDirectory.Dump();
NB Pour obtenir Domain\UserName
j'utiliserais System.Security.Principal.WindowsIdentity.GetCurrent().Name
plutôt que Environment.UserDomainName+@"\"+Environment.UserName
.
( nouveau: disponible depuis la version LinqPad v4.45.05 (beta) )
Util.WriteCsv (Customers, @"c:\temp\customers.csv");
Cela écrira le contenu de la table Customers
dans le fichier CSV c:\temp\customers.csv
. Vous pouvez également trouver un bel exemple sur la façon d'utiliser Util.WriteCsv
et d'afficher les données CSV dans la fenêtre de résultats de Linqpad ici .
Conseils:
Pour obtenir / créer un fichier CSV qui se trouve dans le même répertoire que la requête, vous pouvez utiliser:
var csvFile=Util.CurrentQueryPath.Replace(".linq", ".csv");
Si la table est volumineuse, utilisez ObjectTrackingEnabled = false;
avant d'écrire le CSV pour éviter de le mettre en cache en mémoire.
Si vous souhaitez générer un tableau au format XML plutôt que sous forme de fichier séparé par des virgules, vous pouvez le faire comme:
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();
Cet exemple renvoie tous les éléments ayant l'attribut attr1
qui contient la valeur "a"
d'un fichier XML qui porte le même nom que la requête et est contenu dans le même chemin. Consultez ce lien pour plus d'exemples de code.
var pwd = Util.GetPassword("UserXY");
Cela récupérera le mot de passe du gestionnaire de mots de passe intégré de LinqPad. Pour créer et modifier le mot de passe, ouvrez l' élément de menu "Gestionnaire de mots de passe" dans le menu "Fichier" de LinqPad. S'il n'y a pas de mot de passe enregistré lorsque vous exécutez le code C #, une boîte de dialogue de mot de passe s'ouvrira vous demandant le mot de passe et vous avez le choix de le créer et de l'enregistrer à la volée en cochant la case Enregistrer le mot de passe (dans l'exemple, le mot de passe pour "UserXY" serait enregistré, et plus tard vous pouvez trouver cette entrée dans le gestionnaire de mots de passe ).
Les avantages sont que vous pouvez stocker le mot de passe dans les LinqScripts que vous créez en toute sécurité, séparément et chiffré dans le profil utilisateur de Windows (il est stocké dans %localappdata%\LINQPad\Passwords
un fichier). LinqPad utilise Windows DPAPI pour protéger le mot de passe.
De plus, le mot de passe est stocké de manière centralisée, donc si vous devez le changer, vous pouvez le faire dans le menu et il s'applique immédiatement à tous les scripts que vous avez créés.
Remarques:
Si vous ne souhaitez pas enregistrer le mot de passe et afficher simplement une boîte de dialogue de mot de passe, vous pouvez utiliser le 2ème paramètre comme suit:
var pwd = Util.GetPassword("UserXY", true);
Cela décochera la case à cocher Enregistrer le mot de passe dans la boîte de dialogue de mot de passe (cependant, l'utilisateur peut toujours le vérifier et choisissez de sauvegarder quand même).
Si vous avez besoin que le mot de passe soit stocké dans a SecureString
, vous pouvez utiliser cette fonction d'aide (nb: pour obtenir la méthode d'extension .ToSecureString()
utilisée, veuillez suivre ce lien sur Stackoverflow - il vous permet également de le reconvertir si nécessaire):
System.Security.SecureString GetPasswordSecure(string Name, bool noDefaultSave=true)
{
return Util.GetPassword(Name, noDefaultSave)
.ToSecureString();
}
Cette méthode fonctionne comme un processeur de commandes. Vous pouvez appeler toutes les commandes que vous connaissez à partir de la console Windows.
Exemple 1 - dir:
Util.Cmd(@"dir C:\");
Cela affichera le résultat du répertoire sans qu'il soit nécessaire .Dump
. Le stocker dans une variable a l'avantage que vous pouvez utiliser d'autres requêtes Linq dessus. Par exemple:
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();
Cela videra tous les fichiers avec les extensions de fichier ".exe" ou ".dll" contenus dans C:\windows\system32
. Le /s
commutateur est utilisé pour récurer tous les sous-répertoires et /b
est utilisé pour le format de sortie nu. Notez que le deuxième paramètre de la méthode Cmd est spécifié pour supprimer la sortie de la console afin d'afficher uniquement le résultat filtré à l'aide de la méthode Dump.
Vous pouvez voir que cela est plus flexible que les caractères génériques que vous avez dir
car vous pouvez utiliser toute la flexibilité du moteur de requête de Linq.
Exemple 2 - éditeur de texte:
Vous pouvez ouvrir un fichier dans le Bloc-notes comme ceci:
var filePath=@"C:\HelloWorld.txt";
Util.Cmd(@"%systemroot%\system32\notepad.exe", filePath);
Affiche les images d'une URL. Exemple:
var url = "http://chart.apis.google.com/chart?cht=p3&chd=s:Uf9a&chs=350x140&chl=January|February|March|April";
Util.Image(url).Dump();
L'utilisation Util.ProgressBar
vous permet d'afficher une barre de progression. Vous pouvez utiliser la classe d'assistance suivante:
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;
}
}
}
Utilisez-le simplement comme le montre l'exemple suivant:
void Main()
{
var pb1= new ProgressBar();
Thread.Sleep(50);
pb1.Update(50, "Doing something"); Thread.Sleep(550);
pb1.Update(100); Thread.Sleep(50);
}
Vous pouvez également utiliser Util.Progress
pour mettre à jour la barre de progression intégrée des LinqPads, par exemple:
Util.Progress = 25; // 25 percent complete
La différence est qu'il ne s'affichera pas dans la fenêtre de résultats et vous ne pouvez pas lui attribuer de message.
Affiche le HTML dans la fenêtre de sortie. Exemple:
Util.RawHtml (new XElement ("h1", "This is a big heading")).Dump();
Vous pouvez utiliser cette fonction d'exemple
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);
}
pour afficher les hyperliens dans la fenêtre de résultats - ou toute action comme l'ouverture de votre éditeur préféré. Usage:
ShowUrl("http://stackoverflow.com", "Check out StackOverflow");
Notez que cette fonction fonctionne toujours, alors new Hyperlinq ("http://myURL", "Web site").Dump();
qu'elle ne fonctionne pas pour certains types d'URL (en particulier, si vous devez passer des noms de port comme ": 1234" dans le cadre de l'URL).
Lit l'entrée de la console. Exemple:
int age = Util.ReadLine<int> ("Enter your age");
En tant que synonyme de Util.ReadLine<string>()
, vous pouvez également utiliser Console.ReadLine()
.
Mais il y a plus! Vous pouvez créer un analyseur JSON simple avec l'extrait de code suivant - très utile, par exemple si vous souhaitez analyser et tester une chaîne JSON à la volée. Enregistrez l'extrait suivant sous le nom JSONAnalyzer.linq à l' aide d'un éditeur de texte , puis ouvrez-le dans LinqPad (c'est pour ajouter facilement les références à la volée):
<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");
}
Maintenant, vous pouvez l'exécuter et coller simplement une chaîne JSON du presse-papiers dans la console - il utilisera la Dump
fonction pour l'afficher comme un objet bien - et vous obtenez également les messages d'erreur de l'analyseur à l'écran pour résoudre les problèmes. Très utile pour le débogage d'AJAX.
Si vous devez effacer la fenêtre de résultats dans votre script, utilisez:
Util.ClearResults();
Utilisez-le en haut de votre script, ou - si vous exécutez plusieurs requêtes dans un script - vous devez attendre l'entrée de l'utilisateur avant de vider l'écran (par exemple en le précédant de Util.ReadLine
).
Il est également intéressant de noter que vous pouvez modifier la sortie de la .Dump()
méthode. Implémentez simplement l'interface ICustomMemberProvider
, par exemple
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 vous créez une instance de cette classe, comme
var obj1 = new test();
obj1.Dump("Test");
alors il affichera seulement Hint
, constMember1
, constMember2
et myprop
, mais pas la propriété xyz
:
Si vous devez afficher une boîte de message, regardez ici comment le faire.
Par exemple, vous pouvez afficher une InputBox à l'aide du code suivant
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'oubliez pas d'appuyer sur F4 et d'ajouter Microsoft.VisualBasic.dll et ses espaces de noms pour que cela fonctionne)
( nouveau: disponible depuis la version LinqPad v4.52.1 (beta) )
Vous permet d'exécuter un autre script LINQPad à partir de votre script ou de votre propre programme .NET ou service Windows (en référençant la version LINQPad4-AnyCPU de LINQPad.exe
). Il exécute le script comme le lprun.exe
ferait l' outil de ligne de commande .
Exemples:
const string path=@"C:\myScripts\LinqPad\";
var dummy=new LINQPad.QueryResultFormat(); // needed to call Util.Run
Util.Run(path+"foo.linq", dummy);
Cet exemple exécute le script foo.linq
, qui contient l'exemple de code suivant:
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");
}
Il vous permet de vérifier si le script a été exécuté depuis l'intérieur de l'interface graphique LinqPad ou via lprun.exe
ou avec Util.Run
.
Remarque: les variantes d'appel suivantes peuvent être utiles:
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 vous utilisez LinqToSQL , vous souhaiterez peut-être rendre les modifications permanentes (pour les opérations d' insertion / mise à jour / suppression ). Étant donné que le contexte de la base de données est implicitement créé par LinqPad, vous devez appeler SubmitChanges()
après chaque modification comme indiqué ci-dessous.
Exemples pour la base de données (LinqPad-) Northwind :
Insérer
var newP = new Products() { ProductID=pID, CategoryID=cID,
ProductName="Salmon#"+pID.ToString() };
Products.InsertOnSubmit(newP);
SubmitChanges();
Mettre à jour
var prod=(from p in Products
where p.ProductName.Contains("Salmon")
select p).FirstOrDefault();
prod.ProductName="Trout#"+prod.ProductID.ToString();
SubmitChanges();
Supprimer
var itemsToDelete=Products.Where(p=> p.ProductName.Contains("Salmon") ||
p.ProductName.Contains("Trout"));
foreach(var item in itemsToDelete) { Products.DeleteOnSubmit(item); }
SubmitChanges();
Remarque: afin d'obtenir des identifiants valides pour les exemples précédents, vous pouvez utiliser:
var cID = (from c in Categories
where c.CategoryName.Contains("Seafood")
select c).FirstOrDefault().CategoryID;
var pID = Products.Count()+1;
avant de les invoquer.
Si vous utilisez Entity Framework , vous souhaiterez peut-être rendre les modifications permanentes également (pour les opérations d' insertion / mise à jour / suppression ). Étant donné que le contexte de la base de données est implicitement créé par LinqPad, vous devez appeler SaveChanges()
après chaque modification comme indiqué ci-dessous.
Les exemples sont fondamentalement les mêmes que précédemment pour LinqToSQL , mais vous devez les utiliser à la SaveChanges()
place, et pour insérer et supprimer les méthodes ont également changé.
Insérer
var newP = new Products() { ProductID=pID, CategoryID=cID,
ProductName="Salmon#"+pID.ToString() };
Products.Add(newP);
SaveChanges();
Mettre à jour
var prod=(from p in Products
where p.ProductName.Contains("Salmon")
select p).FirstOrDefault();
prod.ProductName="Trout#"+prod.ProductID.ToString();
SaveChanges();
Supprimer
var itemsToDelete=Products.Where(p=> p.ProductName.Contains("Salmon") ||
p.ProductName.Contains("Trout"));
foreach(var item in itemsToDelete) { Products.Remove(item); }
SaveChanges();
Remarque: afin d'obtenir des identifiants valides pour les exemples précédents, vous pouvez utiliser:
var cID = (from c in Categories
where c.CategoryName.Contains("Seafood")
select c).FirstOrDefault().CategoryID;
var pID = Products.Count()+1;
avant de les invoquer.
Dans LinqPad , le contexte de base de données est appliqué automatiquement en utilisant la zone de liste déroulante en haut et en sélectionnant la bonne base de données pour votre requête. Mais parfois, il est utile de le référencer explicitement, par exemple si vous copiez du code de votre projet hors de Visual Studio et le collez dans LinqPad.
Votre extrait de code extrait du projet Visual Studio ressemble très probablement à ceci:
var prod=(from p in dc.Products
where p.ProductName.Contains("Salmon")
select p).FirstOrDefault();
prod.ProductName="Trout#"+prod.ProductID.ToString();
dc.SaveChanges();
Que faire maintenant dc
? Bien sûr, vous pouvez supprimer chaque occurrence de dc.
dans votre requête, mais c'est beaucoup plus facile. Il suffit d'ajouter
var dc=this; // UserQuery
en haut de votre extrait de code comme ceci:
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();
}
et le code fonctionnera instantanément!
Utilisation de LinqPad avec OleDb, conversion d'une table de données en objet Linq, requêtes SQL dans Linq
L'extrait de code suivant vous aide à utiliser LinqPad avec OleDb. Ajoutez à System.Data.OleDb
partir de l' System.Data
assembly aux propriétés de la requête, puis collez le code suivant dans 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();
Ajoutez maintenant une connexion SqlServer à LinqPad et ajoutez la base de données Northwind afin d'exécuter cet exemple.
NB: Si vous souhaitez simplement obtenir la base de données et le serveur de la connexion actuellement sélectionnée, vous pouvez utiliser cet extrait de code:
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();
}
Vous pouvez même convertir myDS
en Linq, les réponses à la question suivante montrent comment le faire: Bons exemples d'utilisation du mot clé dynamique .NET 4 avec Linq
Un autre exemple: supposons que votre DBA vous donne une requête SQL et que vous souhaitiez analyser les résultats dans LinqPad - bien sûr dans Linq, pas dans SQL. Ensuite, vous pouvez effectuer les opérations suivantes:
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;
}
Dans cet exemple, la requête SELECT du DBA est simplement «jetée dans» le texte de la commande, et les résultats sont filtrés et classés par ville.
Bien sûr, ceci est un exemple simplifié, votre DBA vous donnerait probablement un script plus complexe, mais vous avez l'idée: ajoutez simplement une classe de résultat de prise en charge qui contient tous les champs de la clause SELECT et vous pourrez ensuite l'utiliser directement .
Vous pouvez même prendre le résultat d'une procédure stockée de cette façon et l'utiliser dans Linq. Comme vous pouvez le voir, dans cet exemple, je me fiche du type de données et de mon utilisation dynamic
pour l'exprimer.
Il s'agit donc vraiment de programmation rapide pour pouvoir analyser rapidement les données. Vous ne devriez pas faire cela dans votre application réelle pour diverses raisons (injection SQL, car vous pouvez utiliser EF depuis le début, etc.).
Dessiner un graphique dans LinqPad, partie 1
Pour utiliser les exemples ci - dessous, appuyez sur F4et ajouter System.Windows.dll
, System.Windows.Forms.dll
, WindowsFormsIntegration.dll
, PresentationCore.dll
et PresentationFramework.dll
à votre programme LINQPad et également ajouter l'espace de noms System.Windows.Shapes
.
Le premier exemple trace simplement une ligne:
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");
Le deuxième exemple montre comment afficher le graphique dans LinqPad à l'aide du PanelManager. Normalement, LinqPad ne prend en charge que les objets Wpf. Cet exemple utilise System.Windows.Forms.Integration.WindowsFormsHost
pour rendre un Windows.Forms.PictureBox
disponible (il a été inspiré par ceci ):
// 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);
}
Cela créera le graphique suivant (les éléments de panneau "Graphique" et "Image" sont ajoutés par les exemples ci-dessus):
Si vous souhaitez afficher les images de la base de données Northwind, vous pouvez effectuer les opérations suivantes:
Modifiez le nom du fichier image en «NorthwindPics.jpg», puis ajoutez le code suivant au début de la méthode Main () du deuxième exemple :
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();
}
Il lira le premier enregistrement de la table Employés et affichera l'image.
Consultez les liens suivants pour en savoir plus:
Formes et dessin de base dans les visualiseurs personnalisés WPF
LinqPad
Remarque: vous pouvez également obtenir la même chose sans PanelManager, comme le montre l'exemple suivant, que j'ai vu ici :
// 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();
}
Il utilise la .Dump()
commande pour l'afficher. Vous pouvez invoquer image.Dump()
plusieurs fois et cela ajoutera l'image.
Dessiner un graphique dans LinqPad, partie 2
L'exemple suivant, inspiré de cet article, montre comment implémenter un traceur de fonctions simple dans Linqpad 5 en utilisant 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;
}
Il utilise la capacité de LinqPad pour afficher les formulaires Windows dans le panneau des résultats.
Ajouter des références (presse ) : , , et ajouter tous les espaces de noms de ces assemblées.
F4
System.Drawing.dll
System.Windows.Forms.dll
System.Windows.Forms.DataVisualization.dll
Conseils supplémentaires / lectures complémentaires:
Vous souhaitez utiliser LinqPad dans Visual Studio ? Voici comment vous pouvez faire cela .
Besoin d'avoir LinqPad comme "application portable" ? Lisez ici comment faire cela.
Le site Web de Joe pour LinqPad est toujours une excellente source. Dans LinqPad, Help -> What's New
vous donne des conseils sur les nouvelles fonctions et méthodes. Le forum LinqPad contient également des conseils utiles.
Également très utile: cet article sur le débogage Linq (Pad).
À utiliser lprun.exe
pour exécuter des requêtes LINQ dans vos scripts de commandes. Lisez cet article pour plus de détails. Par exemple:
echo Customers.Take(100) > script.txt
lprun -lang=e -cxname=CompanyServer.CustomerDb script.txt
dans cet exemple, la requête est une simple expression LINQ. Bien sûr, vous pouvez également préparer des requêtes complexes en utilisant -lang=program
pour activer le mode programme.
Vous pouvez écrire des méthodes d'extension et les stocker dans l' onglet Mes requêtes sur le côté gauche de LinqPad: Le dernier élément de l'arborescence est nommé Mes extensions ; double-cliquez dessus pour ouvrir un fichier dans lequel vous pouvez écrire des extensions disponibles pour toutes vos requêtes. Mettez-les simplement dans la classe statique publique MyExtensions
et utilisez la Main()
méthode pour inclure des tests pour vos extensions.
Dump est une méthode d'extension globale et SubmitChanges provient de l'objet DataContext qui est un objet System.Data.Linq.DataContext.
LP n'ajoute que Dump and Disassemble pour autant que je sache. Bien que je recommande vivement de l'ouvrir dans Reflector pour voir ce qu'il y a d'autre qui peut être utilisé. L'une des choses les plus intéressantes est l'espace de noms LINQPad.Util qui contient quelques avantages utilisés par LINQPad en interne.
.Dump()
ou sur toute autre méthode dans l'éditeur de source, appuyez sur F12 pour "refléter". Ceci est maintenant intégré à l'outil!
J'ai atteint la limite de texte StackOverflow dans ma réponse précédente , mais il y a encore plus d'extensions intéressantes dans LinqPad. Je voudrais mentionner l'un d'entre eux:
.Dump()
)Depuis la version 5.42 beta de LinqPad, vous pouvez intégrer des fonctions JavaScript et les appeler directement depuis votre code C #. Bien que cela ait quelques limitations (par rapport à JSFiddle), c'est un bon moyen de tester rapidement du code JavaScript dans LinqPad.
Exemple:
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");
}
Dans cet exemple, une fonction jsFoo
avec un paramètre est préparée et stockée dans la variable literal
. Ensuite, il est rendu et appelé via .Dump().HtmlElement.InvokeScript(...)
, en passant le paramètre testparam
.
La fonction JavaScript utilise external.Log(...)
pour afficher du texte dans les fenêtres de sortie de LinqPad et alert(...)
pour afficher un message contextuel.
Vous pouvez simplifier cela en ajoutant la classe / les méthodes d'extension suivantes :
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);
}
}
Ensuite, vous pouvez appeler l'exemple précédent comme suit:
// 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");
Cela a le même effet, mais est plus facile à lire (si vous avez l'intention de faire plus de JavaScript ;-)).
Une autre option, si vous aimez les expressions Lambda et que vous n'aimez pas spécifier le nom de la fonction sous forme de chaîne à chaque fois que vous l'appelez, vous pouvez faire:
var jsFoo = ScriptExtension.CreateJavaScript(
@"function jsFoo(x) { ... }");
ScriptExtension.RunJavaScript(() => jsFoo, "testparam");
à condition que vous ayez ajouté la fonction d'assistance
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);
}
à la classe ScriptExtension
. Cela résoudra le nom de variable que vous avez utilisé (ici jsFoo
) qui se trouve être le même nom que la fonction JavaScript elle-même (notez comment l'expression lambda est utilisée pour résoudre le nom de la variable, cela ne peut pas être fait nameof(paramName)
à l'intérieur de la fonction).
Parfois, il est utile d' écraser le texte que vous avez vidé plutôt que de le mettre dans une nouvelle ligne, par exemple si vous effectuez une requête de longue durée et que vous souhaitez afficher sa progression, etc. (voir également ProgressBar ci-dessous). Cela peut être fait en utilisant a DumpContainer
, vous pouvez l'utiliser comme indiqué dans le
Exemple 1:
void Main()
{
var dc = new DumpContainer("Doing something ... ").Dump("Some Action");
System.Threading.Thread.Sleep(3000); // wait 3 seconds
dc.Content += "Done.";
}
Notez que pour certains objets plus complexes, vous devrez peut-être utiliser dc.UpdateContent(obj);
plutôt que dc.Content=...
.
Exemple 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!");
}
L'affichage de la progression peut également être effectué en utilisant une barre de progression comme suit:
Exemple:
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";
}
Ceci est similaire à l'exemple de vidage précédent, mais montre cette fois une belle animation de barre de progression.
Saviez-vous que vous pouvez écrire des tests unitaires dans LinqPad? Par exemple, vous pouvez utiliser le framework xUnit. Il est disponible via le support NUGET de LinqPad - via F4- dans le clic de dialogue Add NUGET..... Voici une description étape par étape de l' utilisation de xUnit avec LinqPad V5 ou V6.
Si j'en découvre plus, je mettrai à jour cette réponse