Czy ktoś ma pełną listę metod i metod rozszerzających LINQPad, takich jak
.Dump()
SubmitChanges()
Czy ktoś ma pełną listę metod i metod rozszerzających LINQPad, takich jak
.Dump()
SubmitChanges()
Odpowiedzi:
LINQPad definiuje dwie metody rozszerzające (w LINQPad.Extensions), a mianowicie Dump()
i Disassemble()
. Dump()
zapisuje do okna wyjściowego przy użyciu programu formatującego dane wyjściowe LINQPad i jest przeciążony, aby umożliwić określenie nagłówka:
typeof (int).Assembly.Dump ();
typeof (int).Assembly.Dump ("mscorlib");
Możesz również określić maksymalną głębokość rekurencji, aby zastąpić domyślne 5 poziomów:
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 () deasembluje każdą metodę do IL
, zwracając wynik w postaci ciągu:
typeof (Uri).GetMethod ("GetHashCode").Disassemble().Dump();
Oprócz tych dwóch metod rozszerzających istnieje kilka przydatnych metod statycznych w LINQPad.Util. Są one udokumentowane w autouzupełnianiu i obejmują:
LINQPad udostępnia również klasę HyperLinq. Ma to dwa cele: pierwszym jest wyświetlanie zwykłych hiperłączy:
new Hyperlinq ("www.linqpad.net").Dump();
new Hyperlinq ("www.linqpad.net", "Web site").Dump();
new Hyperlinq ("mailto:user@domain.com", "Email").Dump();
Możesz to połączyć z Util.HorizontalRun
:
Util.HorizontalRun (true,
"Check out",
new Hyperlinq ("http://stackoverflow.com", "this site"),
"for answers to programming questions.").Dump();
Wynik:
Sprawdź tę witrynę, aby uzyskać odpowiedzi na pytania programistyczne.
Drugim celem HyperLinq jest dynamiczne budowanie zapytań:
// 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();
Możesz również napisać własne metody rozszerzające w LINQPad. Przejdź do „Moje zapytania” i kliknij zapytanie o nazwie „Moje rozszerzenia”. Wszystkie zdefiniowane tutaj typy / metody są dostępne dla wszystkich zapytań:
void Main()
{
"hello".Pascal().Dump();
}
public static class MyExtensions
{
public static string Pascal (this string s)
{
return char.ToLower (s[0]) + s.Substring(1);
}
}
W 4.46 (.02) wprowadzono nowe klasy i metody :
Ponadto klasa Hyperlinq obsługuje teraz Action delegata który będzie wywoływany po kliknięciu łącza, umożliwiając reagowanie na nie w kodzie, a nie tylko jako łącze do zewnętrznych stron internetowych.
DumpContainer
to klasa, która dodaje blok do okna wyjściowego, w którym można zamienić jego zawartość.
UWAGA! Pamiętaj, aby.Dump()
DumpContainer
siebie w odpowiednim miejscu.
Używać:
var dc = new DumpContainer();
dc.Content = "Test";
// further down in the code
dc.Content = "Another test";
OnDemand
to metoda rozszerzenia, która nie wyprowadza zawartości swojego parametru do okna wyjściowego, ale zamiast tego dodaje klikalne łącze, które po kliknięciu zastąpi łącze .Dump()
treścią ed parametru. Jest to świetne rozwiązanie w przypadku czasami potrzebnych struktur danych, które są kosztowne lub zajmują dużo miejsca.
UWAGA! Pamiętaj o .Dump()
wynikach rozmowyOnDemand
w odpowiednim miejscu.
Aby z niego skorzystać:
Customers.OnDemand("Customers").Dump(); // description is optional
Util.ProgressBar
to klasa, która może wyświetlać graficzny pasek postępu w oknie wyjściowym, który można zmieniać w miarę przesuwania się kodu.
UWAGA! Pamiętaj by.Dump()
w odpowiednim miejscu obiekt Util.ProgressBar.
Aby z niego skorzystać:
var pb = new Util.ProgressBar("Analyzing data");
pb.Dump();
for (int index = 0; index <= 100; index++)
{
pb.Percent = index;
Thread.Sleep(100);
}
Oprócz dobrze znanej myQuery.Dump("Query result:")
, inną cechą, o której warto wspomnieć, jest Util
klasa: zawiera wiele całkiem przydatnych metod (niektóre z nich wspomniałem, ale jest ich o wiele więcej).
Interesujące jest również to, że możesz modyfikować sposób Dump()
działania .
Na koniec pokażę ci, jak możesz wprowadzać zmiany na stałe (tj. Wstawiać, aktualizować, usuwać zapytania LINQ) za pomocą SubmitChanges()
lubSaveChanges()
a także jak uzyskać dostęp do wewnętrznego obiektu połączenia LinqPad.
Podsumowując, pokażę Ci, jak możesz stworzyć prostą grafikę 2D wewnątrz LinqPada (rysowanie linii, bitmap lub funkcji ).
Oto zbiór wbudowanych funkcji LinqPad (z mojego własnego doświadczenia z narzędziem):
(parametry dostępne w LinqPad v5.03.08 i nowszych)
Wszyscy użytkownicy LinqPad znają i uwielbiają .Dump()
metodę rozszerzenia, która zużywa i drukuje (prawie) wszystko.
Ale czy wiesz, że dostępnych jest kilka parametrów? Spójrz na ten fragment kodu:
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
W 1-ci przykład drukuje tylko zmienne a
i c
oraz skór b
i d
The 2-ci przykładowe nie odwrotnie (zauważ, że określa ona tylko 2 z dostępnych parametrów). Zmienne y
i z
nie mogą być ukryte pojedynczo, ponieważ nie znajdują się na najwyższym poziomie.
Dostępne są następujące parametry ( wszystkie są opcjonalne ):
description
[string] - zawiera opis obiektu do zrzutudepth
[int?] - ogranicza głębokość rekurencyjnej inspekcji obiektówtoDataGrid
[bool] - jeśli prawda, dane wyjściowe są formatowane jako datagrid, a nie jako RichTextexclude
[string] - jeśli podasz listę zmiennych oddzielonych przecinkami, zostaną one wykluczone z wyniku (w przykładzie „a, c”: b
i d
są wyświetlane, a
ac
są ukryte)exclude
[string] z prefiksem „+” - prefiks odwraca logikę parametru wykluczenia. Oznacza to, że jeśli podasz listę zmiennych oddzielonych przecinkami, wszystkie poza określonymi są ukryte (w przykładzie „+ b, d”: b
id
są wyświetlane, a wszystkie inne są ukryte)var x=Util.ToExpando(obj, "a, c", "b, d"); x.Dump();
.OnDemand("click me").Dump();
zamiast .Dump()
, wyświetli się link, który możesz kliknąć, aby rozwinąć. Przydatne, jeśli chcesz sprawdzić wartości, np. Util.OnDemand("Customer-ID: " + customerObject.ID.ToString(), ()=>customerObject, false).Dump();
Aby zawsze pokazywać ID domyślnie, ale ujawniać szczegóły customerObject
tylko wtedy, gdy jesteś zainteresowany.Bardziej zaawansowane tematy dotyczące zrzutu można znaleźć tu i tam .
To nie jest rozszerzenie LinqPad, ale raczej klasa .NET, ale ponieważ jest przydatne, i tak o tym wspomnę. Możesz uzyskać wiele przydatnych informacji, których możesz użyć w swoich skryptach, takich jak:
Environment.UserDomainName.Dump();
Environment.MachineName.Dump();
Environment.UserName.Dump();
Environment.CurrentDirectory.Dump();
Environment.SystemDirectory.Dump();
NB Do uzyskania Domain\UserName
użyłbym System.Security.Principal.WindowsIdentity.GetCurrent().Name
raczej niż Environment.UserDomainName+@"\"+Environment.UserName
.
( nowe: dostępne od wersji LinqPad v4.45.05 (beta) )
Util.WriteCsv (Customers, @"c:\temp\customers.csv");
Spowoduje to zapisanie zawartości tabeli Customers
do pliku CSV c:\temp\customers.csv
. Możesz również znaleźć dobry przykład, jak używać, Util.WriteCsv
a następnie wyświetlać dane CSV w oknie wyników Linqpada tutaj .
Poradnik:
Aby pobrać / utworzyć plik CSV, który znajduje się w tym samym katalogu co zapytanie, możesz użyć:
var csvFile=Util.CurrentQueryPath.Replace(".linq", ".csv");
Jeśli tabela jest duża, użyj jej ObjectTrackingEnabled = false;
przed napisaniem pliku CSV, aby uniknąć buforowania go w pamięci.
Jeśli chcesz wyprowadzić tabelę w formacie XML, a nie jako plik rozdzielany przecinkami, możesz to zrobić w następujący sposób:
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();
Ten przykład zwraca wszystkie elementy mające atrybut, attr1
który zawiera wartość "a"
z pliku XML, który ma taką samą nazwę jak zapytanie i jest zawarty w tej samej ścieżce. Sprawdź ten link, aby uzyskać więcej przykładów kodu.
var pwd = Util.GetPassword("UserXY");
Spowoduje to pobranie hasła z wbudowanego menedżera haseł LinqPad. Aby utworzyć i zmienić hasło, otwórz pozycję menu „Menedżer haseł” w menu „Plik” w LINQPad. Jeśli nie ma zapisanego hasła po uruchomieniu kodu C #, otworzy się okno dialogowe hasła z prośbą o podanie hasła i możesz je utworzyć i zapisać w locie, zaznaczając pole wyboru Zapisz hasło (w tym przykładzie hasło dla "UserXY" zostałby zapisany, a później możesz znaleźć ten wpis w menedżerze haseł ).
Zaletą jest to, że możesz bezpiecznie przechowywać hasło w LinqScripts, które tworzysz w bezpieczny sposób, oddzielnie i zaszyfrowane w profilu użytkownika systemu Windows (jest przechowywane %localappdata%\LINQPad\Passwords
jako plik). LinqPad używa Windows DPAPI do ochrony hasła.
Ponadto hasło jest przechowywane centralnie, więc jeśli chcesz je zmienić, możesz to zrobić w menu i od razu zostanie zastosowane do wszystkich utworzonych skryptów.
Uwagi:
Jeśli nie chcesz zapisywać hasła i po prostu wyświetlasz okno dialogowe hasła, możesz użyć drugiego parametru w następujący sposób:
var pwd = Util.GetPassword("UserXY", true);
Spowoduje to odznaczenie zapisywania hasła w oknie dialogowym hasła (jednak użytkownik nadal może je sprawdzić i wybierz opcję zapisania mimo wszystko).
Jeśli chcesz, aby hasło było przechowywane w a SecureString
, możesz użyć tej funkcji pomocniczej (uwaga: aby uzyskać .ToSecureString()
używaną metodę rozszerzenia , skorzystaj z tego linku w Stackoverflow - umożliwia ona również konwersję z powrotem w razie potrzeby):
System.Security.SecureString GetPasswordSecure(string Name, bool noDefaultSave=true)
{
return Util.GetPassword(Name, noDefaultSave)
.ToSecureString();
}
Ta metoda działa jak procesor poleceń. Możesz wywołać wszystkie znane polecenia z konsoli systemu Windows.
Przykład 1 - reż:
Util.Cmd(@"dir C:\");
Spowoduje to wyświetlenie wyniku katalogu bez potrzeby .Dump
. Przechowywanie go w zmiennej ma tę zaletę, że można na niej używać dalszych zapytań Linq. Na przykład:
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();
Spowoduje to zrzucenie wszystkich plików z rozszerzeniami „.exe” lub „.dll” zawartych w C:\windows\system32
. Plik/s
Przełącznik służy do recurse wszystkie podkatalogi i/b
służy do gołej formatu wyjściowego. Należy zauważyć, że drugi parametr metody Cmd jest określony w celu pominięcia danych wyjściowych konsoli, aby wyświetlić tylko przefiltrowany wynik przy użyciu metody Dump.
Jak widzisz, jest to bardziej elastyczne niż posiadane symbole wieloznaczne dir
ponieważ możesz wykorzystać pełną elastyczność silnika zapytań Linq.
Przykład 2 - edytor tekstu:
Możesz otworzyć plik w Notatniku w następujący sposób:
var filePath=@"C:\HelloWorld.txt";
Util.Cmd(@"%systemroot%\system32\notepad.exe", filePath);
Wyświetla obrazy z adresu URL. Przykład:
var url = "http://chart.apis.google.com/chart?cht=p3&chd=s:Uf9a&chs=350x140&chl=January|February|March|April";
Util.Image(url).Dump();
Użycie Util.ProgressBar
umożliwia wyświetlenie paska postępu. Możesz użyć następującej klasy pomocnika:
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;
}
}
}
Po prostu użyj go, jak pokazuje poniższy przykład:
void Main()
{
var pb1= new ProgressBar();
Thread.Sleep(50);
pb1.Update(50, "Doing something"); Thread.Sleep(550);
pb1.Update(100); Thread.Sleep(50);
}
Możesz alternatywnie użyć Util.Progress
do aktualizacji zintegrowanego paska postępu LinqPads, na przykład:
Util.Progress = 25; // 25 percent complete
Różnica polega na tym, że nie wyświetli się w oknie wyników i nie możesz przypisać do niego wiadomości.
Wyświetla HTML w oknie wyjściowym. Przykład:
Util.RawHtml (new XElement ("h1", "This is a big heading")).Dump();
Możesz użyć tej przykładowej funkcji
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);
}
aby pokazać hiperłącza w oknie wyników - lub dowolne działania, takie jak otwarcie ulubionego edytora. Stosowanie:
ShowUrl("http://stackoverflow.com", "Check out StackOverflow");
Zauważ, że ta funkcja zawsze działa, podczas gdy new Hyperlinq ("http://myURL", "Web site").Dump();
nie działa w przypadku niektórych adresów URL (szczególnie, jeśli musisz podać nazwy portów, takie jak „: 1234” jako część adresu URL).
Odczytuje dane wejściowe z konsoli. Przykład:
int age = Util.ReadLine<int> ("Enter your age");
Jako synonim słowa Util.ReadLine<string>()
możesz również użyć Console.ReadLine()
.
Ale to nie wszystko! Możesz utworzyć prosty parser JSON za pomocą następującego fragmentu kodu - całkiem przydatne, na przykład, jeśli chcesz przeanalizować i przetestować ciąg JSON w locie. Zapisz następujący fragment kodu jako JSONAnalyzer.linq za pomocą edytora tekstu, a następnie otwórz go w LinqPad (ma to na celu łatwe dodawanie odniesień w locie):
<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");
}
Teraz możesz go uruchomić i po prostu wkleić ciąg JSON ze schowka do konsoli - użyje Dump
funkcji, aby ładnie wyświetlić go jako obiekt - a także otrzymasz komunikaty o błędach parsera na ekranie, aby naprawić problemy. Bardzo przydatne do debugowania AJAX.
Jeśli chcesz wyczyścić okno wyników w skrypcie, użyj:
Util.ClearResults();
Albo użyj go na górze skryptu, albo - jeśli wykonujesz wiele zapytań w skrypcie - powinieneś poczekać na wejście użytkownika przed wyczyszczeniem ekranu (np. Poprzedzając go Util.ReadLine
).
Interesujące jest również to, że możesz zmienić wynik .Dump()
metody. Wystarczy zaimplementować interfejs ICustomMemberProvider
np
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
}
Jeśli utworzysz instancję tej klasy, na przykład
var obj1 = new test();
obj1.Dump("Test");
to będzie tylko wyjście Hint
, constMember1
, constMember2
, i myprop
, ale nie właściwość xyz
:
Jeśli chcesz wyświetlić skrzynkę wiadomości, zobacz , jak to zrobić.
Na przykład możesz wyświetlić InputBox przy użyciu następującego kodu
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
}
}
(nie zapomnij nacisnąć F4 i dodać Microsoft.VisualBasic.dll i jego przestrzenie nazw, aby to zadziałało)
( nowe: dostępne od wersji LinqPad v4.52.1 (beta) )
Umożliwia uruchomienie innego skryptu LINQPad z poziomu skryptu lub z własnego programu .NET lub usługi systemu Windows (przez odwołanie do wersji LINQPad4-AnyCPU LINQPad.exe
). Wykonuje skrypt tak, jak lprun.exe
zrobiłoby to narzędzie wiersza poleceń .
Przykłady:
const string path=@"C:\myScripts\LinqPad\";
var dummy=new LINQPad.QueryResultFormat(); // needed to call Util.Run
Util.Run(path+"foo.linq", dummy);
Ten przykład uruchamia skrypt foo.linq
, który zawiera następujący przykładowy kod:
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");
}
Pozwala sprawdzić, czy skrypt został uruchomiony z poziomu GUI LinqPad lub przez lprun.exe
lub z Util.Run
.
Uwaga: Pomocne mogą być następujące warianty wywołania:
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
Jeśli używasz LinqToSQL , możesz chcieć wprowadzić zmiany na stałe (dla operacji wstawiania / aktualizowania / usuwania ). Ponieważ kontekst bazy danych jest niejawnie tworzony przez LinqPad, musisz wywołać SubmitChanges()
każdą zmianę, jak pokazano poniżej.
Przykłady bazy danych (LinqPad-) Northwind :
Wstawić
var newP = new Products() { ProductID=pID, CategoryID=cID,
ProductName="Salmon#"+pID.ToString() };
Products.InsertOnSubmit(newP);
SubmitChanges();
Aktualizacja
var prod=(from p in Products
where p.ProductName.Contains("Salmon")
select p).FirstOrDefault();
prod.ProductName="Trout#"+prod.ProductID.ToString();
SubmitChanges();
Usunąć
var itemsToDelete=Products.Where(p=> p.ProductName.Contains("Salmon") ||
p.ProductName.Contains("Trout"));
foreach(var item in itemsToDelete) { Products.DeleteOnSubmit(item); }
SubmitChanges();
Uwaga: aby uzyskać prawidłowe identyfikatory z poprzednich przykładów, możesz użyć:
var cID = (from c in Categories
where c.CategoryName.Contains("Seafood")
select c).FirstOrDefault().CategoryID;
var pID = Products.Count()+1;
zanim je przywołasz.
Jeśli używasz Entity Framework , możesz również wprowadzić zmiany na stałe (w przypadku operacji wstawiania / aktualizowania / usuwania ). Ponieważ kontekst bazy danych jest niejawnie tworzony przez LinqPad, musisz wywołać SaveChanges()
każdą zmianę, jak pokazano poniżej.
Przykłady są w zasadzie takie same jak wcześniej dla LinqToSQL , ale musisz użyćSaveChanges()
, a metody wstawiania i usuwania również się zmieniły.
Wstawić
var newP = new Products() { ProductID=pID, CategoryID=cID,
ProductName="Salmon#"+pID.ToString() };
Products.Add(newP);
SaveChanges();
Aktualizacja
var prod=(from p in Products
where p.ProductName.Contains("Salmon")
select p).FirstOrDefault();
prod.ProductName="Trout#"+prod.ProductID.ToString();
SaveChanges();
Usunąć
var itemsToDelete=Products.Where(p=> p.ProductName.Contains("Salmon") ||
p.ProductName.Contains("Trout"));
foreach(var item in itemsToDelete) { Products.Remove(item); }
SaveChanges();
Uwaga: aby uzyskać prawidłowe identyfikatory z poprzednich przykładów, możesz użyć:
var cID = (from c in Categories
where c.CategoryName.Contains("Seafood")
select c).FirstOrDefault().CategoryID;
var pID = Products.Count()+1;
zanim je przywołasz.
W LINQPad The kontekst baza danych jest stosowana automatycznie za pomocą combobox na górze i wybierając odpowiednią bazę dla Twojego zapytania. Ale czasami warto odwołać się do niego jawnie, na przykład jeśli skopiujesz kod z projektu z programu Visual Studio i wkleisz go do LinqPad.
Twój fragment kodu pobrany z projektu programu Visual Studio najprawdopodobniej wygląda następująco:
var prod=(from p in dc.Products
where p.ProductName.Contains("Salmon")
select p).FirstOrDefault();
prod.ProductName="Trout#"+prod.ProductID.ToString();
dc.SaveChanges();
Co teraz zrobić dc
? Oczywiście możesz usunąć każde wystąpienie dc.
w zapytaniu, ale jest to znacznie łatwiejsze. Poprostu dodaj
var dc=this; // UserQuery
na górę fragmentu kodu, na przykład:
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();
}
a kod zadziała natychmiast!
Korzystanie z LinqPad z OleDb, konwersja obiektu datatable na obiekt Linq, zapytania SQL w Linq
Poniższy fragment kodu ułatwia korzystanie z LinqPad z OleDb. Dodaj System.Data.OleDb
z System.Data
zestawu do właściwości zapytania, a następnie wklej następujący kod do 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();
Teraz dodaj połączenie SqlServer do LinqPad i dodaj bazę danych Northwind, aby uruchomić ten przykład.
NB: Jeśli chcesz tylko uzyskać bazę danych i serwer aktualnie wybranego połączenia, możesz użyć tego fragmentu kodu:
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();
}
Możesz nawet zamienić myDS
na Linq, odpowiedzi na następujące pytanie pokazują, jak to zrobić: Ładne przykłady użycia dynamicznego słowa kluczowego .NET 4 z Linq
Jeszcze jeden przykład: załóżmy, że Twój DBA wysyła zapytanie SQL i chcesz przeanalizować wyniki w LinqPad - oczywiście w Linq, a nie w SQL. Następnie możesz wykonać następujące czynności:
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;
}
W tym przykładzie zapytanie SELECT DBA jest po prostu „wrzucane” do tekstu polecenia, a wyniki są filtrowane i sortowane według miasta.
Oczywiście jest to uproszczony przykład, Twój DBA prawdopodobnie dałby ci bardziej złożony skrypt, ale masz pomysł: po prostu dodaj pomocniczą klasę wyników, która zawiera wszystkie pola z klauzuli SELECT, a następnie możesz jej bezpośrednio użyć .
Możesz nawet pobrać wynik z procedury składowanej w ten sposób i użyć go w Linq. Jak widać, w tym przykładzie nie obchodzi mnie typ danych i używam go dynamic
do wyrażenia.
Tak naprawdę chodzi o szybkie programowanie, aby móc szybko analizować dane. Nie powinieneś tego robić w swojej prawdziwej aplikacji z różnych powodów (iniekcja SQL, ponieważ możesz używać EF od początku itp.).
Narysuj grafikę w LinqPad, część 1
Aby korzystać z przykładów poniżej, naciśnij F4i dodać System.Windows.dll
, System.Windows.Forms.dll
, WindowsFormsIntegration.dll
, PresentationCore.dll
i PresentationFramework.dll
do swojego programu LINQPad a także dodać przestrzeń nazw System.Windows.Shapes
.
1-ci przykład po prostu rysuje linię:
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");
The 2nd przykład pokazuje, jak można wyświetlacz graficzny w LINQPad za pomocą PanelManager. Zwykle LinqPad obsługuje tylko obiekty WPF. W tym przykładzie użyto System.Windows.Forms.Integration.WindowsFormsHost
zrobić Windows.Forms.PictureBox
dostępna (to był inspirowany przez to ):
// 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);
}
Stworzy to następującą grafikę (elementy panelu „Grafika” i „Obraz” są dodawane do powyższych przykładów):
Jeśli chcesz wyświetlić obrazy z bazy danych Northwind, możesz wykonać następujące czynności:
Zmień nazwę pliku obrazu na „NorthwindPics.jpg”, a następnie dodaj następujący kod na początku metody Main () w drugim przykładzie :
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();
}
Odczyta pierwszy rekord z tabeli Pracownicy i wyświetli obraz.
Sprawdź poniższe łącza, aby dowiedzieć się więcej:
Kształty i podstawowe rysunki w niestandardowych wizualizatorach WPF
LinqPad
Uwaga: możesz osiągnąć to samo bez PanelManagera, co pokazuje poniższy przykład, który tutaj widziałem :
// 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();
}
Używa .Dump()
polecenia, aby go wyświetlić. Możesz wywołać image.Dump()
wiele razy, a to dołączy obraz.
Narysuj grafikę w LinqPad, część 2
Poniższy przykład, zainspirowany tym postem, pokazuje, jak zaimplementować prosty ploter funkcyjny w Linqpad 5 przy użyciu 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;
}
Wykorzystuje możliwości LinqPada do wyświetlania formularzy Windows w panelu wyników.
Dodaj referencje (naciśnij ) : , , i dodanie wszystkich nazw tych zespołów.
F4
System.Drawing.dll
System.Windows.Forms.dll
System.Windows.Forms.DataVisualization.dll
Dodatkowe wskazówki / dalsze czytanie:
Chcesz używać LinqPad w programie Visual Studio ? Oto jak możesz to zrobić .
Chcesz mieć LinqPad jako „aplikację przenośną” ? Przeczytaj tutaj, jak to zrobić.
Witryna Joe dla LinqPad jest zawsze doskonałym źródłem. Wewnątrz LinqPad Help -> What's New
znajdziesz wskazówki dotyczące nowych funkcji i metod. LINQPad Forum zawiera również pomocnych wskazówek.
Również bardzo pomocny: ten artykuł o debugowaniu Linq (Pad).
Służy lprun.exe
do uruchamiania zapytań LINQ w skryptach wsadowych. Przeczytaj ten artykuł, aby uzyskać więcej informacji. Na przykład: w
echo Customers.Take(100) > script.txt
lprun -lang=e -cxname=CompanyServer.CustomerDb script.txt
tym przykładzie zapytanie jest prostym wyrażeniem LINQ. Oczywiście możesz również przygotować złożone zapytania używając -lang=program
do aktywacji trybu programu.
Możesz pisać metody rozszerzające i przechowywać je w zakładce Moje zapytania po lewej stronie LinqPad: Ostatni element drzewa nosi nazwę Moje rozszerzenia ; kliknij go dwukrotnie, aby otworzyć plik, w którym możesz zapisać rozszerzenia dostępne dla wszystkich zapytań. Po prostu umieść je w publicznej klasie statycznej MyExtensions
i użyj Main()
metody, aby dołączyć testy dla swoich rozszerzeń.
Dump jest globalną metodą rozszerzającą, a SubmitChanges pochodzi z obiektu DataContext, który jest obiektem System.Data.Linq.DataContext.
LP dodaje tylko Dump and Disassemble, o ile wiem. Chociaż gorąco polecam otwarcie go w Reflektorze, aby zobaczyć, co jeszcze można użyć. Jedną z bardziej interesujących rzeczy jest przestrzeń nazw LINQPad.Util, która zawiera pewne dodatki używane wewnętrznie przez LINQPad.
.Dump()
lub jakąkolwiek inną metodę w edytorze źródłowym, naciśnij F12, aby „odzwierciedlić”. Jest to teraz wbudowane w narzędzie!
Osiągnąłem limit tekstu StackOverflow w mojej poprzedniej odpowiedzi , ale wciąż jest więcej fajnych rozszerzeń w LinqPad. O jednym z nich chciałbym wspomnieć:
.Dump()
)Od wersji 5.42 beta LinqPad możesz osadzać funkcje JavaScript i wywoływać je bezpośrednio z kodu C #. Chociaż ma to pewne ograniczenia (w porównaniu z JSFiddle), jest to dobry sposób na szybkie przetestowanie kodu JavaScript w LinqPad.
Przykład:
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");
}
W tym przykładzie funkcja jsFoo
z jednym parametrem jest przygotowywana i zapisywana w zmiennej literal
. Następnie jest renderowany i wywoływany przez .Dump().HtmlElement.InvokeScript(...)
, przekazując parametr testparam
.
Funkcja JavaScript używa external.Log(...)
do wyprowadzania tekstu w oknach wyjściowych LinqPad ialert(...)
do wyświetlania wyskakującego komunikatu.
Możesz to uprościć, dodając następujące klasy / metody rozszerzenia:
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);
}
}
Następnie możesz wywołać poprzedni przykład w następujący sposób:
// 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");
Ma to ten sam efekt, ale jest łatwiejsze do odczytania (jeśli zamierzasz robić więcej JavaScript ;-)).
Inną opcją, jeśli lubisz wyrażenia lambda i nie lubisz określać nazwy funkcji jako łańcucha za każdym razem, gdy ją wywołujesz, możesz zrobić:
var jsFoo = ScriptExtension.CreateJavaScript(
@"function jsFoo(x) { ... }");
ScriptExtension.RunJavaScript(() => jsFoo, "testparam");
pod warunkiem, że dodałeś funkcję pomocniczą
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);
}
do klasy ScriptExtension
. Spowoduje to rozpoznanie użytej nazwy zmiennej (tutaj jsFoo
), która jest tą samą nazwą, co sama funkcja JavaScript (zwróć uwagę, jak wyrażenie lambda jest używane do rozpoznawania nazwy zmiennej, nie można tego zrobić, używając nameof(paramName)
wewnątrz funkcji).
Czasami warto nadpisać zrzucony tekst , zamiast umieszczać go w nowym wierszu, na przykład, jeśli wykonujesz długotrwałe zapytanie i chcesz pokazać jego postęp itp. (Zobacz także ProgressBar poniżej). Można to zrobić za pomocą pliku DumpContainer
, możesz go użyć, jak pokazano w
Przykład 1:
void Main()
{
var dc = new DumpContainer("Doing something ... ").Dump("Some Action");
System.Threading.Thread.Sleep(3000); // wait 3 seconds
dc.Content += "Done.";
}
Zwróć uwagę, że w przypadku bardziej złożonych obiektów może być konieczne użycie dc.UpdateContent(obj);
zamiast dc.Content=...
.
Przykład 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!");
}
Postęp można również wyświetlić za pomocą ProgressBar w następujący sposób:
Przykład:
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";
}
Jest to podobne do poprzedniego przykładu zrzutu, ale tym razem pokazuje ładną animację paska postępu.
Czy wiesz, że możesz pisać testy jednostkowe w LinqPad? Na przykład możesz użyć struktury xUnit. Jest dostępny poprzez obsługę NUGET LinqPad - przez F4- w oknie dialogowym kliknij Add NUGET..... Oto opis krok po kroku, jak używać xUnit z LinqPad V5 lub V6.
Jeśli dowiem się więcej, zaktualizuję tę odpowiedź