Хтось має повний перелік методів та методів розширення LINQPad, таких як
.Dump()
SubmitChanges()
Хтось має повний перелік методів та методів розширення LINQPad, таких як
.Dump()
SubmitChanges()
Відповіді:
LINQPad визначає два способи розширення (у LINQPad.Extensions), а саме Dump()
і Disassemble()
. Dump()
записує у вікно виводу, використовуючи вихідний формат LINQPad, і перевантажується, щоб дати вам заголовок:
typeof (int).Assembly.Dump ();
typeof (int).Assembly.Dump ("mscorlib");
Ви також можете вказати максимальну глибину рекурсії, щоб змінити типовий рівень 5:
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 () розбирає будь-який метод на IL
, повертаючи результат у рядку:
typeof (Uri).GetMethod ("GetHashCode").Disassemble().Dump();
Окрім цих двох методів розширення, в LINQPad.Util є кілька корисних статичних методів. Вони задокументовані в автозавершенні і включають:
LINQPad також забезпечує клас HyperLinq. Це має дві цілі: перше - відображення звичайних гіперпосилань:
new Hyperlinq ("www.linqpad.net").Dump();
new Hyperlinq ("www.linqpad.net", "Web site").Dump();
new Hyperlinq ("mailto:user@domain.com", "Email").Dump();
Ви можете комбінувати це з Util.HorizontalRun
:
Util.HorizontalRun (true,
"Check out",
new Hyperlinq ("http://stackoverflow.com", "this site"),
"for answers to programming questions.").Dump();
Результат:
Перегляньте цей сайт, щоб отримати відповіді на питання програмування.
Друга мета HyperLinq - динамічно будувати запити:
// 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();
Ви також можете написати свої власні методи розширення в LINQPad. Перейдіть до розділу "Мої запити" та натисніть запит під назвою "Мої розширення". Будь-які типи / методи, які тут визначені, доступні для всіх запитів:
void Main()
{
"hello".Pascal().Dump();
}
public static class MyExtensions
{
public static string Pascal (this string s)
{
return char.ToLower (s[0]) + s.Substring(1);
}
}
У 4.46 (.02) були введені нові класи та методи :
Крім того, клас Hyperlinq тепер підтримує делегата Action, який буде викликаний при натисканні на посилання, що дозволяє реагувати на нього в коді, а не просто посилатися на зовнішні веб-сторінки.
DumpContainer
- клас, який додає блок у вікно виводу, який може замінити його вміст.
ПРИМІТКА! Пам'ятайте .Dump()
про DumpContainer
себе у відповідному місці.
Використовувати:
var dc = new DumpContainer();
dc.Content = "Test";
// further down in the code
dc.Content = "Another test";
OnDemand
- це метод розширення, який не виводить вміст свого параметра у вікно виводу, а замість цього додасть посилання, що можна натискати, що при натисканні на нього замінить посилання на .Dump()
зміст змісту параметра. Це чудово підходить для іноді потрібних структур даних, які затратні або займають багато місця.
ПРИМІТКА! Запам’ятайте .Dump()
результати дзвінків OnDemand
у відповідному місці.
Щоб використовувати його:
Customers.OnDemand("Customers").Dump(); // description is optional
Util.ProgressBar
це клас, який може відображати графічну панель прогресу всередині вікна виводу, яку можна змінити, коли код рухається далі.
ПРИМІТКА! Пам'ятайте .Dump()
про об'єкт Util.ProgressBar у відповідному місці.
Щоб використовувати його:
var pb = new Util.ProgressBar("Analyzing data");
pb.Dump();
for (int index = 0; index <= 100; index++)
{
pb.Percent = index;
Thread.Sleep(100);
}
Крім відомої myQuery.Dump("Query result:")
, ще одна особливість, яку слід згадати, - цеUtil
клас: він містить багато досить зручних методів (деякі з них я вже згадував, але їх набагато більше).
Також цікаво те, що ви можете змінити спосіб Dump()
роботи .
Нарешті я покажу вам, як можна робити зміни постійними (тобто вставляти, оновлювати, видаляти запити LINQ), використовуючи SubmitChanges()
або SaveChanges()
як ви можете отримати доступ до об'єкта внутрішнього з'єднання LinqPad.
А щоб завершити це, я покажу вам, як ви можете створити просту двовимірну графіку всередині LinqPad (малювання ліній, растрових зображень або функцій) ).
Отже, ось колекція вбудованих функцій LinqPad (з власного досвіду роботи з інструментом):
(параметри доступні в LinqPad v5.03.08 і вище)
Усі користувачі LinqPad знають і люблять .Dump()
метод розширення, який споживає та друкує (майже) все.
Але чи знаєте ви, що є пара параметрів? Погляньте на цей фрагмент коду:
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
У першому прикладі друкує тільки змінні a
і c
приховування b
і d
, тим другий приклад робить протилежне (зверніть увагу , що він визначає тільки 2 з доступних параметрів). Змінні y
і z
не можуть бути приховані за окремо, тому що вони не знаходяться на рівні верхньої.
Доступні такі параметри ( усі необов’язково ):
description
[string] - надає опис для скидання об'єктаdepth
[int?] - обмежує глибину обстеження предметів рекурсивноtoDataGrid
[bool] - якщо вірно, вихід буде форматований як сітка даних, а не як RichTextexclude
[рядок] - якщо ви надаєте список змінних комами, вони будуть виключені з виводу (у прикладі "a, c": b
і d
показані, a
і c
приховані)exclude
[рядок] з префіксом "+" - префікс інвертує логіку параметра виключення. Це означає, що якщо ви надаєте список змінних комами, всі вказані, крім вказаних, приховані (у прикладі "+ b, d": b
іd
показані, всі інші приховані)var x=Util.ToExpando(obj, "a, c", "b, d"); x.Dump();
.OnDemand("click me").Dump();
замість цього .Dump()
, воно відображатиме посилання, на яке ви можете натиснути, щоб розгорнути. Корисно, якщо ви хочете перевірити значення, наприклад, Util.OnDemand("Customer-ID: " + customerObject.ID.ToString(), ()=>customerObject, false).Dump();
завжди показувати ідентифікатор за замовчуванням, але розкривати деталі, customerObject
лише якщо вас цікавить.Більш вдосконалені теми про дамп можна знайти тут і там .
Це не розширення LinqPad, а скоріше клас .NET, але оскільки він корисний, я все одно його згадаю. Ви можете отримати багато корисної інформації, яку можете використовувати у своїх сценаріях, таких як:
Environment.UserDomainName.Dump();
Environment.MachineName.Dump();
Environment.UserName.Dump();
Environment.CurrentDirectory.Dump();
Environment.SystemDirectory.Dump();
Примітка: Для отримання Domain\UserName
я б System.Security.Principal.WindowsIdentity.GetCurrent().Name
скоріше використовував , ніж Environment.UserDomainName+@"\"+Environment.UserName
.
( новий: доступний з версії LinqPad v4.45.05 (бета) )
Util.WriteCsv (Customers, @"c:\temp\customers.csv");
Це запише вміст таблиці Customers
у файл CSV c:\temp\customers.csv
. Ви також можете знайти хороший приклад використання Util.WriteCsv
та відображення даних CSV у вікні результатів Linqpad тут .
Підказки:
Щоб отримати / створити файл CSV, який знаходиться в тій самій каталозі, що і запит, ви можете використовувати:
var csvFile=Util.CurrentQueryPath.Replace(".linq", ".csv");
Якщо таблиця велика, використовуйте ObjectTrackingEnabled = false;
перед тим, як записати CSV, щоб уникнути кешування її в пам'яті.
Якщо ви хочете вивести таблицю у форматі XML, а не як розділений комами файл, ви можете це зробити так:
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();
Цей приклад повертає всі елементи, що мають атрибут, attr1
який містить значення "a"
з файлу XML, який має те саме ім'я, що і запит, і міститься в тому ж шляху. Перегляньте це посилання, щоб отримати більше зразків коду.
var pwd = Util.GetPassword("UserXY");
Це дозволить отримати пароль з вбудованого менеджера паролів LinqPad. Для того, щоб створити і змінити пароль, відкрийте пункт меню «Менеджер паролів» в меню «Файл» з LINQPad. Якщо під час запуску коду C # не збережено жодного пароля, відкриється діалогове вікно з проханням ввести пароль, і ви зможете створити та зберегти його на льоту, встановивши прапорець для збереження пароля (у прикладі пароля для "UserXY" буде збережено, і пізніше ви можете знайти цей запис у Менеджері паролів ).
Переваги полягають у тому, що ви можете зберігати пароль у створених вами LinqScripts надійно, окремо та зашифровано у профілі користувача Windows (він зберігається у %localappdata%\LINQPad\Passwords
вигляді файлу). LinqPad використовує Windows DPAPI для захисту пароля.
Також пароль зберігається централізовано, тому якщо вам потрібно змінити його, ви можете зробити це в меню, і воно негайно стосується всіх створених вами сценаріїв.
Примітки:
Якщо ви не хочете зберегти пароль і просто відкрити діалогове вікно пароля, ви можете скористатися другим параметром наступним чином:
var pwd = Util.GetPassword("UserXY", true);
Це зніме галочку для збереження пароля у діалоговому вікні пароля (проте користувач все ще може перевірити його та будь-який спосіб зберегти).
Якщо вам потрібно зберегти пароль у файліSecureString
, ви можете скористатися цією допоміжною функцією (nb: щоб .ToSecureString()
використати метод розширення , будь ласка, перейдіть за цим посиланням на Stackoverflow - він також дозволяє вам перетворити його назад, якщо потрібно):
System.Security.SecureString GetPasswordSecure(string Name, bool noDefaultSave=true)
{
return Util.GetPassword(Name, noDefaultSave)
.ToSecureString();
}
Цей метод працює як командний процесор. Ви можете викликати всі відомі команди з консолі Windows.
Приклад 1 - dir:
Util.Cmd(@"dir C:\");
Це виведе результат каталогу без необхідності в .Dump
ньому. Збереження його в змінній має перевагу в тому, що ви можете використовувати подальші запити Linq на ній. Наприклад:
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();
Це скине всі файли з розширеннями файлів ".exe" або ".dll", що містяться в C:\windows\system32
. /s
Перемикач використовується для рекурсії всіх підкаталогів і /b
використовується для голого вихідного формату. Зауважте, що другий параметр методу Cmd заданий для придушення виходу консолі, щоб показати лише відфільтрований результат за допомогою методу Dump.
Ви можете бачити, що це більш гнучко, ніж у вас є макіяж, dir
оскільки ви можете використовувати повну гнучкість механізму запитів Linq.
Приклад 2 - текстовий редактор:
Ви можете відкрити файл у Блокноті так:
var filePath=@"C:\HelloWorld.txt";
Util.Cmd(@"%systemroot%\system32\notepad.exe", filePath);
Відображає зображення з URL-адреси. Приклад:
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
дозволяє відображати панель прогресу. Ви можете використовувати наступний хелперний клас:
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;
}
}
}
Просто використовуйте його, як показано в наступному прикладі:
void Main()
{
var pb1= new ProgressBar();
Thread.Sleep(50);
pb1.Update(50, "Doing something"); Thread.Sleep(550);
pb1.Update(100); Thread.Sleep(50);
}
Можна також використовувати Util.Progress
для оновлення інтегрованої панелі прогресу LinqPads, наприклад:
Util.Progress = 25; // 25 percent complete
Різниця полягає в тому, що він не відображатиметься у вікні результатів, і ви не можете призначити йому повідомлення.
Відображає HTML у вікні виводу. Приклад:
Util.RawHtml (new XElement ("h1", "This is a big heading")).Dump();
Ви можете використовувати цю прикладну функцію
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);
}
показувати гіперпосилання у вікні результату - або будь-які дії, такі як відкриття улюбленого редактора. Використання:
ShowUrl("http://stackoverflow.com", "Check out StackOverflow");
Зауважте, що ця функція завжди працює, але new Hyperlinq ("http://myURL", "Web site").Dump();
не працює для деяких типів URL-адрес (особливо, якщо вам доведеться передавати назви портів типу ": 1234" як частина URL-адреси).
Читає вхід з консолі. Приклад:
int age = Util.ReadLine<int> ("Enter your age");
Як синонім Util.ReadLine<string>()
, ви можете також використовувати Console.ReadLine()
.
Але є більше! Ви можете створити простий синтаксичний аналізатор JSON із наступним фрагментом - досить корисним, наприклад, якщо ви хочете проаналізувати і протестувати рядок JSON на льоту. Збережіть наступний фрагмент як JSONAnalyzer.linq за допомогою текстового редактора, а потім відкрийте його в LinqPad (для легкого додавання посилань):
<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");
}
Тепер ви можете запустити його і просто вставити рядок JSON з буфера обміну в консоль - вона використовуватиме Dump
функцію, щоб красиво відобразити її як об’єкт - і ви також отримаєте повідомлення про помилки аналізатора на екрані для усунення проблем. Дуже корисно для налагодження AJAX.
Якщо вам потрібно очистити вікно результатів всередині вашого сценарію, використовуйте:
Util.ClearResults();
Або використовуйте його у верхній частині сценарію, або - якщо ви виконуєте кілька запитів у скрипті - вам слід дочекатися введення користувачем, перш ніж закривати екран (наприклад, попередньо перед цим Util.ReadLine
).
Також цікаво те, що ви можете змінити вихідний .Dump()
метод. Просто реалізуйте інтерфейс ICustomMemberProvider
, наприклад
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
}
Якщо ви створюєте екземпляр цього класу, наприклад
var obj1 = new test();
obj1.Dump("Test");
то він буде виводити тільки Hint
, constMember1
, constMember2
, і myprop
, а не власність xyz
:
Якщо вам потрібно відобразити скриньку повідомлень, подивіться тут, як це зробити.
Наприклад, ви можете відобразити InputBox, використовуючи наступний код
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
}
}
(не забудьте натиснути F4 та додати Microsoft.VisualBasic.dll та його простори імен, щоб зробити цю роботу)
( новий: доступний з версії LinqPad v4.52.1 (бета) )
Дозволяє запускати інший скрипт LINQPad в межах вашого сценарію або в межах вашої власної програми .NET або служби Windows (посилаючись на версію LINQPad4-AnyCPU LINQPad.exe
). Він виконує сценарій так, як це lprun.exe
зробив інструмент командного рядка .
Приклади:
const string path=@"C:\myScripts\LinqPad\";
var dummy=new LINQPad.QueryResultFormat(); // needed to call Util.Run
Util.Run(path+"foo.linq", dummy);
Цей приклад запускає скрипт foo.linq
, який містить такий зразок коду:
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");
}
Це дозволяє перевірити, чи сценарій запускався з GUI LinqPad або через lprun.exe
або з Util.Run
.
Примітка . Наступні варіанти виклику можуть бути корисними:
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
Якщо ви використовуєте LinqToSQL , ви можете зробити зміни постійними (для операцій вставлення / оновлення / видалення ). Оскільки контекст бази даних неявно зроблений LinqPad, вам потрібно дзвонити SubmitChanges()
після кожної зміни, як показано нижче.
Приклади для (LinqPad-) бази даних Northwind :
Вставити
var newP = new Products() { ProductID=pID, CategoryID=cID,
ProductName="Salmon#"+pID.ToString() };
Products.InsertOnSubmit(newP);
SubmitChanges();
Оновлення
var prod=(from p in Products
where p.ProductName.Contains("Salmon")
select p).FirstOrDefault();
prod.ProductName="Trout#"+prod.ProductID.ToString();
SubmitChanges();
Видалити
var itemsToDelete=Products.Where(p=> p.ProductName.Contains("Salmon") ||
p.ProductName.Contains("Trout"));
foreach(var item in itemsToDelete) { Products.DeleteOnSubmit(item); }
SubmitChanges();
Примітка. Щоб отримати дійсні ідентифікатори для попередніх прикладів, ви можете використовувати:
var cID = (from c in Categories
where c.CategoryName.Contains("Seafood")
select c).FirstOrDefault().CategoryID;
var pID = Products.Count()+1;
перш ніж викликати їх.
Якщо ви використовуєте Entity Framework , ви також можете змінити постійні зміни (для операцій вставлення / оновлення / видалення ). Оскільки контекст бази даних неявно зроблений LinqPad, вам потрібно дзвонити SaveChanges()
після кожної зміни, як показано нижче.
Приклади в основному такі ж, як і раніше для LinqToSQL , але вам потрібно скористатися SaveChanges()
замість цього, а також для вставки та видалення методів змінилося.
Вставити
var newP = new Products() { ProductID=pID, CategoryID=cID,
ProductName="Salmon#"+pID.ToString() };
Products.Add(newP);
SaveChanges();
Оновлення
var prod=(from p in Products
where p.ProductName.Contains("Salmon")
select p).FirstOrDefault();
prod.ProductName="Trout#"+prod.ProductID.ToString();
SaveChanges();
Видалити
var itemsToDelete=Products.Where(p=> p.ProductName.Contains("Salmon") ||
p.ProductName.Contains("Trout"));
foreach(var item in itemsToDelete) { Products.Remove(item); }
SaveChanges();
Примітка. Щоб отримати дійсні ідентифікатори для попередніх прикладів, ви можете використовувати:
var cID = (from c in Categories
where c.CategoryName.Contains("Seafood")
select c).FirstOrDefault().CategoryID;
var pID = Products.Count()+1;
перш ніж викликати їх.
У LINQPad , то контекст бази даних застосовуються автоматично за допомогою випадаючого в верхньому і вибрати правильну базу даних для вашого запиту. Але іноді корисно посилатися на нього явно, наприклад, якщо ви скопіюєте якийсь код із свого проекту з Visual Studio і вставите його в LinqPad.
Ваш фрагмент коду, взятий з проекту Visual Studio, швидше за все, виглядає приблизно так:
var prod=(from p in dc.Products
where p.ProductName.Contains("Salmon")
select p).FirstOrDefault();
prod.ProductName="Trout#"+prod.ProductID.ToString();
dc.SaveChanges();
Тепер що робити dc
? Звичайно, ви можете видалити кожне виникнення dc.
запиту, але це набагато простіше. Просто додайте
var dc=this; // UserQuery
вгорі вашого фрагмента так:
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();
}
і код запрацює миттєво!
Використання LinqPad з OleDb, перетворення даних у об'єкт Linq, SQL запити в Linq
Наступний фрагмент коду допоможе вам використовувати LinqPad з OleDb. Додайте System.Data.OleDb
із System.Data
збірки властивості запиту, а потім вставте наступний код у 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();
Тепер додайте підключення SqlServer до LinqPad та додайте базу даних Northwind для запуску цього прикладу.
Примітка: Якщо ви просто хочете отримати базу даних та сервер поточного обраного з'єднання, ви можете використовувати цей фрагмент коду:
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();
}
Ви навіть можете конвертувати myDS
в Linq, відповіді на наступне питання показують, як це зробити: Приємні приклади використання .NET 4 динамічного ключового слова з Linq
Ще один приклад: припустимо, що ваша DBA дає вам запит SQL, і ви хочете проаналізувати результати в LinqPad - звичайно, в Linq, а не в SQL. Тоді ви можете зробити наступне:
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;
}
У цьому прикладі запит SELECT DBA просто "кидається" в текст команди, а результати фільтруються та впорядковуються City.
Звичайно, це спрощений приклад, ваша DBA, ймовірно, дасть вам складніший сценарій, але ви отримуєте ідею: Просто додайте підтримуючий результат результату, який містить усі поля з пункту SELECT, і тоді ви можете безпосередньо використовувати його .
Ви навіть можете взяти результат зі збереженої процедури таким чином і використовувати його в Linq. Як бачите, у цьому прикладі я не дбаю про тип даних і використовую його dynamic
для вираження.
Тож мова йде дійсно про швидке програмування, щоб мати можливість швидко аналізувати дані. Ви не повинні робити це у вашій реальній програмі з різних причин (ін'єкція SQL, тому що ви можете використовувати EF з самого початку тощо).
Намалюйте графіку на LinqPad, частина 1
Для того, щоб використовувати приклади нижче, натисніть F4і додати System.Windows.dll
, System.Windows.Forms.dll
, WindowsFormsIntegration.dll
, PresentationCore.dll
і PresentationFramework.dll
до вашій програмі LINQPad , а також додати простір імен System.Windows.Shapes
.
Перший приклад просто малює лінію:
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");
На 2 - й приклад показує , як ви можете відобразити графіку в LINQPad за допомогою PanelManager. Зазвичай LinqPad підтримує лише Wpf-об’єкти. Цей приклад використовується System.Windows.Forms.Integration.WindowsFormsHost
для створення Windows.Forms.PictureBox
доступного (це надихнуло це ):
// 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);
}
Це створить наступну графіку (елементи панелі "Графіка" та "Малюнок" додаються прикладами вище):
Якщо ви хочете відобразити зображення з бази даних Northwind, ви можете зробити наступне:
Змініть ім'я файлу зображення на "NorthwindPics.jpg", а потім додайте наступний код на початку методу Main () другого прикладу :
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();
}
Він прочитає перший запис із таблиці співробітників та відобразить малюнок.
Перегляньте наступні посилання, щоб дізнатися більше:
Фігури та основний малюнок у спеціалізованих візуалізаторах WPF
LinqPad
Примітка. Те ж можна досягти і без PanelManager, як показано в наступному прикладі, який я бачив тут :
// 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();
}
Для його .Dump()
відображення використовується команда. Ви можете викликати image.Dump()
кілька разів, і це додасть зображення.
Намалюйте графіку на LinqPad, частина 2
Наступний приклад, натхненний цією публікацією, показує, як реалізувати простий графік функцій у Linqpad 5 за допомогою 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;
}
Він використовує можливість LinqPad відображати форми Windows на панелі результатів.
Додати посилання (прес ) : , , і додати всі простори імен з цих збірок.
F4
System.Drawing.dll
System.Windows.Forms.dll
System.Windows.Forms.DataVisualization.dll
Додаткові підказки / подальше читання:
Хочете використовувати LinqPad у Visual Studio ? Ось як ви можете це зробити .
Потрібно мати LinqPad як "портативний додаток" ? Прочитайте тут, як це зробити.
Веб-сайт Джо для LinqPad - це завжди чудове джерело. Всередині LinqPad Help -> What's New
дає вам підказки про нові функції та методи. Форум LinqPad також містить корисні підказки.
Також дуже корисно: Ця стаття про налагодження Linq (Pad).
Використовуйте lprun.exe
для запуску запитів LINQ у пакетних сценаріях. Прочитайте цю статтю для більш детальної інформації. Наприклад:
echo Customers.Take(100) > script.txt
lprun -lang=e -cxname=CompanyServer.CustomerDb script.txt
У цьому прикладі запит є простим виразом LINQ. Звичайно, ви також можете підготувати складні запити, використовуючи -lang=program
для активації програмного режиму.
Ви можете написати способи розширення та зберегти їх на вкладці " Мої запити" з лівої сторони LinqPad: Останній елемент дерева називається " Мої розширення" ; двічі клацніть по ньому, щоб відкрити файл, куди ви можете написати розширення, доступні для всіх ваших запитів. Просто введіть їх у загальнодоступний статичний клас MyExtensions
та використовуйте Main()
метод для включення тестів для ваших розширень.
Дамп - це глобальний метод розширення, і SubmitChanges походить від об'єкта DataContext, який є об'єктом System.Data.Linq.DataContext.
Наскільки я знаю, LP додає лише Dump and Disassemble. Хоча я б дуже рекомендував відкрити його в Reflector, щоб побачити, що ще можна використати. Однією з найцікавіших речей є простір імен LINQPad.Util, який містить деякі смакові якості, які використовує LINQPad всередині.
.Dump()
або будь-який інший метод у вихідному редакторі, натисніть F12, щоб "відобразити". Це тепер вбудовано в інструмент!
Досягнуто ліміту тексту StackOverflow в моїй попередній відповіді , але в LinqPad є ще більш круті розширення. Одну з них я хотів би зазначити:
.Dump()
)З версії 5.42 бета-версії LinqPad ви можете вбудовувати функції JavaScript і викликати їх безпосередньо зі свого коду C #. Хоча це має деякі обмеження (порівняно з JSFiddle), це хороший спосіб швидко протестувати якийсь код JavaScript у LinqPad.
Приклад:
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");
}
У цьому прикладі функція jsFoo
з одним параметром готується і зберігається у змінній literal
. Потім він виводиться і викликається через .Dump().HtmlElement.InvokeScript(...)
, передаючи параметр testparam
.
Функція JavaScript використовується external.Log(...)
для виведення тексту у вихідні вікна LinqPad та alert(...)
для відображення спливаючого повідомлення.
Ви можете спростити це, додавши наступний клас / методи розширення:
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);
}
}
Тоді ви можете назвати попередній приклад таким чином:
// 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");
Це має той же ефект, але його легше читати (якщо ви маєте намір зробити більше JavaScript ;-)).
Ще один варіант, якщо вам подобаються лямбдаські вирази і вам не подобається вказувати ім'я функції як рядок кожного разу, коли ви його викликаєте, ви можете зробити:
var jsFoo = ScriptExtension.CreateJavaScript(
@"function jsFoo(x) { ... }");
ScriptExtension.RunJavaScript(() => jsFoo, "testparam");
за умови, що ви додали функцію помічника
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);
}
до класу ScriptExtension
. Це дозволить вирішити ім'я змінної, яку ви використовували (тут jsFoo
), і це саме те саме ім'я, що і сама функція JavaScript nameof(paramName)
.
Іноді корисно перезаписати текст, який ви скинули, а не вводити його в новий рядок, наприклад, якщо ви виконуєте тривалий запит і хочете показати його прогрес тощо (див. Також ProgressBar нижче). Це можна зробити за допомогою A DumpContainer
, ви можете використовувати його, як показано на
Приклад 1:
void Main()
{
var dc = new DumpContainer("Doing something ... ").Dump("Some Action");
System.Threading.Thread.Sleep(3000); // wait 3 seconds
dc.Content += "Done.";
}
Зауважте, що для деяких більш складних об'єктів, можливо, вам доведеться використовувати, dc.UpdateContent(obj);
а не dc.Content=...
.
Приклад 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!");
}
Показати прогрес можна також за допомогою програми ProgressBar наступним чином:
Приклад:
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";
}
Це схоже на дамп-приклад раніше, але цього разу показує приємну анімацію смужки прогресу.
Чи знаєте ви, що ви можете написати тести на одиницю в LinqPad? Наприклад, ви можете використовувати рамку xUnit. Він доступний через підтримку NUGET LinqPad - через F4- у діалоговому кліку Add NUGET..... Ось покроковий опис, як використовувати xUnit з LinqPad V5 або V6.
Якщо я дізнаюся більше, я оновлю цю відповідь