Ответ 2
Помимо известного 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
В первом примере печатаются только переменные a
и c
и скрываются b
и d
, второй пример делает обратное (обратите внимание, что он указывает только 2 из доступных параметров). Переменные y
и z
не могут быть скрыты индивидуально, потому что они не находятся на верхнем уровне.
Доступны следующие параметры (все необязательные):
-
description
[string] - предоставляет описание для объекта dump
-
depth
[int?] - ограничивает глубину рекурсивно проверенных объектов
-
toDataGrid
[bool] - если true, вывод форматируется как datagrid, а не как RichText
-
exclude
[string] - если вы предоставите список переменных, разделенных запятыми, они будут исключены из вывода (в примере показаны "a, c": b
и d
, a
и c
скрыты)
-
exclude
[string] с префиксом "+" - префикс инвертирует логику параметра exclude. Это означает, что если вы предоставите список переменных, разделенных запятыми, все, кроме указанных, скрыты (в примере показаны "+ b, d": b
и d
, все остальные скрыты)
- сохранение и исключение свойств в переменной (новая с LinqPad V5.09.04):
var x=Util.ToExpando(obj, "a, c", "b, d"); x.Dump();
Первая строка содержит список включенных свойств, вторая строка - список для исключения
- expand on click: Если вы используете
.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();
N.B. Для получения Domain\UserName
я бы использовал System.Security.Principal.WindowsIdentity.GetCurrent().Name
а не [email protected]"\"+Environment.UserName
.
Util.WriteCsv
(новое: доступно с версия 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. Если такого пароля не будет сохранено при запуске кода С#, откроется диалоговое окно с запросом пароля, и вы сможете создать и сохранить его "на лету", установив флажок "Сохранить пароль" (в примере, пароль для "UserXY" будет сохранен, а позже вы сможете найти эту запись в Менеджере паролей).
Преимущества в том, что вы можете хранить пароль в LinqScripts, который вы создаете надежно, отдельно и зашифровываете в профиле пользователя Windows (он хранится в %localappdata%\LINQPad\Passwords
в виде файла). LinqPad использует Windows DPAPI для защиты пароля.
Кроме того, пароль хранится централизованно, поэтому, если вам нужно его изменить, вы можете сделать это в меню, и оно немедленно применимо ко всем созданным сценариям.
Примечания:
-
Если вы не хотите сохранять пароль и просто открывать диалоговое окно с паролем, вы можете использовать второй параметр следующим образом:
var pwd = Util.GetPassword("UserXY", true);
Это снимет флажок сохранения пароля в диалоговом окне пароля (однако пользователь все еще может проверить его и все равно сохранить).
-
Если вам нужен пароль для сохранения в SecureString
, вы можете использовать эту вспомогательную функцию (nb: для использования метода расширения .ToSecureString()
, пожалуйста, следуйте fooobar.com/questions/50316/... - она также позволяет вам конвертировать ее при необходимости):
System.Security.SecureString GetPasswordSecure(string Name, bool noDefaultSave=true)
{
return Util.GetPassword(Name, noDefaultSave)
.ToSecureString();
}
Util.Cmd
Этот метод работает как командный процессор. Вы можете вызывать все команды, которые вы знаете, с консоли Windows.
Пример 1 - dir:
Util.Cmd(@"dir C:\");
Это приведет к выводу результата каталога без необходимости .Dump
его. Сохранение его в переменной имеет то преимущество, что вы можете использовать на нем дополнительные запросы Linq. Например:
var [email protected]"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 [email protected]"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.HorizontalRun
Вы можете использовать эту примерную функцию
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.
![JSON]()
Util.ClearResults
Если вам нужно очистить окно результатов внутри вашего script, используйте:
Util.ClearResults();
Либо используйте его в начале вашего script, либо - если вы выполняете несколько запросов в script - вам нужно дождаться ввода пользователя перед тем, как гасить экран (например, перед тем, как это сделать с Util.ReadLine
).
Пользовательский .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
:
![Linqpad dump]()
Отображение 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
(новое: доступно с версия LinqPad v4.52.1 (бета))
Позволяет запускать еще один LINQPad script из вашего script или в рамках вашей собственной .NET-программы или службы Windows (путем ссылки на версию LINQPad4-AnyCPU LINQPad.exe
). Он выполняет script так же, как это делает инструмент командной строки lprun.exe
.
<сильные > Примеры:
const string [email protected]"C:\myScripts\LinqPad\";
var dummy=new LINQPad.QueryResultFormat(); // needed to call Util.Run
Util.Run(path+"foo.linq", dummy);
В этом примере выполняется script 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", "[email protected]", "[email protected]", "Test Subject" };
#endif
args.Dump("Args");
}
Это позволяет вам отличить, был ли script запущен из 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
SubmitChanges() - Linq To SQL
Если вы используете LinqToSQL, вы можете сделать изменения постоянными (для операций insert/update/delete).
Поскольку контекст базы данных неявно делается 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;
прежде чем вы их вызовите.
SaveChanges() - платформа сущностей
Если вы используете Entity Framework, вы можете также сделать изменения постоянными (для операций insert/update/delete).
Поскольку контекст базы данных неявно выполняется 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 контекст базы данных устанавливается автоматически с помощью выпадающего списка вверху и выбора нужной базы данных для вашего запроса.
Но иногда полезно ссылаться на него явно, например, если вы скопируете код из своего проекта из 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;
в верхней части вашего фрагмента, например:
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, преобразование объекта datatable в 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;
}
В этом примере запрос DBA SELECT просто "брошен" в текст команды, а результаты фильтруются и упорядочиваются по городу.
Конечно, это упрощенный пример, ваш администратор базы данных, вероятно, поддержит вас более сложным script, но вы получите идею: просто добавьте поддерживающий класс результатов, который содержит все поля из предложения 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");
В втором примере показано, как вы можете отображать графику в 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)
{
// /questions/51895/how-to-display-a-picturebox-from-behind-code-in-c/366174#366174
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);
}
Это создаст следующий рисунок (элементы панели "Графика" и "Изображение" добавляются в приведенных выше примерах):
![Showing_Graphic_in_LinqPad]()
Если вы хотите отобразить изображения из базы данных 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();
}
Он прочитает первую запись из таблицы Employees и отобразит изображение.
Ознакомьтесь со следующими ссылками, чтобы узнать больше:
Формы и основной чертеж в 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 с использованием С# 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 в качестве "Портативного приложения" ? Прочитайте здесь, как это сделать.
-
Сайт Joe для LinqPad всегда отличный источник. Внутри LinqPad Help -> What 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: последний элемент дерева называется My Extensions; дважды щелкните по нему, чтобы открыть файл, в котором вы можете писать расширения, доступные для всех ваших запросов. Просто поместите их в открытый статический класс MyExtensions
и используйте метод Main()
для включения тестов для ваших расширений.