Помимо хорошо известного myQuery.Dump("Query result:")
, еще одна особенность, которую стоит упомянуть, это класс Util
: он содержит много весьма удобных методов (некоторые из них я упоминал, но их гораздо больше).
Также интересно то, что вы можете легко изменить способ Dump()
работы .
Наконец, я покажу вам, как вы можете сделать изменения постоянными (т. Е. вставить, обновить, удалить LINQ запросов), используя также SubmitChanges()
или SaveChanges()
как то, как вы можете получить доступ к объекту внутреннего соединения LinqPad.
И в заключение я покажу вам, как вы можете создать простой 2d рисунок внутри LinqPad (рисунок линии, растровые изображения или функции ).
Итак, вот коллекция встроенных функций LinqPad (из моего собственного опыта работы с инструментом):
.Dump ()
(параметры доступны в 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
1-й пример печатает только переменные a
и c
и скрывает b
и d
, Во втором примере действует наоборот (обратите внимание, что он указывает только 2 из доступных параметров).Переменные y
и z
не могут быть скрыты по отдельности, поскольку они не находятся на верхнем уровне.
Доступны следующие параметры ( все являются необязательными ):
description
[строка] - предоставляет описание объекта для сброса depth
[int?] - ограничивает, насколько глубоко объекты рекурсивно проверяются toDataGrid
[bool] - если true, выходные данные форматируются как сетка данных, а не как RichText exclude
[строка] - если вы предоставите список переменных через запятую, они будут исключены из вывода (в примере «a, c»: показаны b
и d
, a
и c
скрыты) exclude
[строка] с префиксом "+" - префикс инвертирует логику параметра исключения.Это означает, что если вы предоставите список переменных через запятую, все, кроме указанных, будут скрыты (в примере «+ b, d»: b
и d
показаны, все остальные скрыты) - хранить включенные и исключенные свойства в переменной (впервые с LinqPad V5.09.04):
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
, только если вас это интересует.
Более сложные темы о Dump могут здесь .
Среда
Это не расширение LinqPad, а скорее класс .NET, но, поскольку оно полезно, я упомянуэто все равно.Вы можете получить много полезной информации, которую можете использовать в своих скриптах, например:
Environment.UserDomainName.Dump();
Environment.MachineName.Dump();
Environment.UserName.Dump();
Environment.CurrentDirectory.Dump();
Environment.SystemDirectory.Dump();
NB Для получения Domain\UserName
я бы использовал System.Security.Principal.WindowsIdentity.GetCurrent().Name
вместо Environment.UserDomainName+@"\"+Environment.UserName
.
Util.WriteCsv
( new: доступно с 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, имя которого совпадает с именем запроса и содержится в том же пути. Проверьте эту ссылку для большего количества примеров кода.
Util.GetPassword
var pwd = Util.GetPassword("UserXY");
Это позволит получить пароль из встроенного в LinqPad менеджера паролей. Чтобы создать и изменить пароль, откройте пункт меню «Менеджер паролей» в меню «Файл» LinqPad. Если при запуске кода C # такой пароль не сохраняется, откроется диалоговое окно с запросом пароля, и у вас есть возможность создать и сохранить его на лету, установив флажок save password (в этом примере пароль для «UserXY» будет сохранен, и позже вы можете найти эту запись в Менеджере паролей ).
Преимущества состоят в том, что вы можете хранить пароль в LinqScripts, который вы создаете безопасно, отдельно и зашифровывать в профиле пользователя Windows (он сохраняется в %localappdata%\LINQPad\Passwords
в виде файла). LinqPad использует Windows DPAPI для защиты пароля.
Кроме того, пароль хранится централизованно, поэтому, если вам нужно изменить его, вы можете сделать это в меню, и он сразу же будет применяться ко всем созданным вами сценариям.
Примечания:
Если вы не хотите сохранять пароль и просто вызывать диалоговое окно ввода пароля, вы можете использовать второй параметр следующим образом:
var pwd = Util.GetPassword("UserXY", true);
При этом флажок сохранить пароль будет снят в диалоговом окне ввода пароля (однако пользователь все равно может проверить его и в любом случае выбрать сохранение).
Если вам требуется, чтобы пароль хранился в SecureString
, вы можете использовать эту вспомогательную функцию (примечание: чтобы использовать метод расширения .ToSecureString()
, перейдите по этой ссылке в Stackoverflow - это также позволяет вам конвертировать его обратно при необходимости):
System.Security.SecureString GetPasswordSecure(string Name, bool noDefaultSave=true)
{
return Util.GetPassword(Name, noDefaultSave)
.ToSecureString();
}
Util.Cmd
Этот метод работает как командный процессор. Вы можете вызывать все известные вам команды из консоли Windows.
Пример 1 - каталог:
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);
Util.Image
Отображение изображений из 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, Util.Progress
Использование 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
Разница в том, что он не будет отображаться в окне результатов, и вы не можете назначить ему сообщение.
Util.RawHtml
Отображение HTML в окне вывода. Пример:
Util.RawHtml (new XElement ("h1", "This is a big heading")).Dump();
Hyperlinq, Util.HorizontRun
Вы можете использовать этот пример функции
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).
Util.ReadLine
Считывает ввод с консоли.Пример:
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.ClearResults();
Либо используйте его в начале вашего скрипта, либо - если вы выполняете несколько запросов в скрипте - вы должны дождаться ввода пользователя, прежде чем очистить экран (например, перед нимс Util.ReadLine
).
Custom .Dump () - ICustomMemberProvider
Также интересно то, что вы можете влиять на вывод метода .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
:
Отображение MessageBox или InputBox в LinqPad
Если вам нужночтобы отобразить окно сообщения, посмотрите здесь как это сделать.
Например, вы можете отобразить 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 и его пространства имен для этой работы)
Util.Run
( new: доступно с 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");
}
Позволяет определить, был ли скрипт запущен из графического интерфейса 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
SubmitChanges () - Linq To SQL
Если вы используете LinqToSQL , вы можете сделать изменения постоянными (для операций вставка / обновление / удаление ).Поскольку контекст базы данных неявно создается LinqPad, вам необходимо вызывать SubmitChanges()
после каждого изменения, как показано ниже.
Примеры для (LinqPad-) Northwind database:
Вставка
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;
, прежде чем вызывать их.
SaveChanges () - Entity Framework
Если вы используете 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;
перед тем, как вызвать их.
this - контекст базы данных
В LinqPad контекст базы данных *1455* устанавливается автоматически с помощью комбинированного списка сверху и выбора базы данных, подходящей для вашего запроса.
Но иногда полезно явно ссылаться на него, например, если вы скопируете некоторый код из вашего проекта из 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();
}
и код будет работать мгновенно!
this.Connection
Использование 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 для запуска этого примера.
N.B.: Если вы просто хотите получить базу данных и сервер текущего выбранного соединения, вы можете использовать этот фрагмент кода:
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
Еще один пример: предположим, что ваш администратор базы данных дает вам 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.
Конечно, это упрощенный пример, ваш администратор базы данных, вероятно, поддержит вас более сложным сценарием, но у вас есть идея: просто добавьте вспомогательный класс результата, который содержит все поля из предложения SELECT, и вы можете напрямую использовать Это.
Таким образом, вы даже можете получить результат из хранимой процедуры и использовать его в Linq. Как вы можете видеть, в этом примере меня не волнует тип данных, и я использую dynamic
для его выражения.
Так что это действительно быстрое программирование, чтобы иметь возможность быстро анализировать данные. Вы не должны делать это в своем реальном приложении по разным причинам (SQL-инъекция, потому что вы можете использовать EF с самого начала и т. Д.).
PanelManager
Рисование графики в LinqPad, часть 1
Чтобы использовать примеры ниже, нажмите F4 и добавьте System.Windows.dll
, System.Windows.Forms.dll
, WindowsFormsIntegration.dll
, PresentationCore.dll
и PresentationFramework.dll
в вашу программу LinqPad, а также добавьте пространство имен System.Windows.Shapes
,
1-й пример просто рисует линию:
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
доступным (он был вдохновлен this ):
// 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», затем добавьте следующий код в начало метода 2-го примера *1547* 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()
несколько раз, и это добавит изображение.
Windows Forms
Рисование графики в 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 Forum также содержит полезные советы.
Также очень полезно: Эта статья об отладке 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()
, чтобы включить тесты для ваших расширений.