Кто-нибудь имеет полный список методов и методов расширения 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:[email protected]", "Email").Dump();
Вы можете комбинировать это с Util.HorizontalRun
:
Util.HorizontalRun (true,
"Check out",
new Hyperlinq ("http://qaru.site/", "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()
ed этого параметра. Это отлично подходит для иногда требуемых структур данных, которые являются дорогостоящими или занимают много места.
ПРИМЕЧАНИЕ! Помните .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.
И чтобы округлить его, я покажу вам, как вы можете создать простой 2d графический внутри 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] - предоставляет описание для объекта dumpdepth
[int?] - ограничивает глубину рекурсивно проверенных объектовtoDataGrid
[bool] - если true, вывод форматируется как datagrid, а не как RichTextexclude
[string] - если вы предоставите список переменных, разделенных запятыми, они будут исключены из вывода (в примере показаны "a, c": b
и d
, a
и c
скрыты)exclude
[string] с префиксом "+" - префикс инвертирует логику параметра 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
только если вы заинтересованы.Более подробные темы о 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
.
(новое: доступно с версия 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. Если такого пароля не будет сохранено при запуске кода С#, откроется диалоговое окно с запросом пароля, и вы сможете создать и сохранить его "на лету", установив флажок "Сохранить пароль" (в примере, пароль для "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();
}
Этот метод работает как командный процессор. Вы можете вызывать все команды, которые вы знаете, с консоли 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);
Отображает изображения с 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.
Если вам нужно очистить окно результатов внутри вашего script, используйте:
Util.ClearResults();
Либо используйте его в начале вашего script, либо - если вы выполняете несколько запросов в script - вам нужно дождаться ввода пользователя перед тем, как гасить экран (например, перед тем, как это сделать с 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 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
Если вы используете 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;
прежде чем вы их вызовите.
Если вы используете 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;
прежде чем вы их вызовите.
В 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();
}
и код будет работать мгновенно!
Использование 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 с самого начала и т.д.).
Нарисуйте рисунок в 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);
}
Это создаст следующий рисунок (элементы панели "Графика" и "Изображение" добавляются в приведенных выше примерах):
Если вы хотите отобразить изображения из базы данных 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()
несколько раз, и он добавит изображение.
Нарисуйте рисунок в 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()
для включения тестов для ваших расширений.
Дамп - это глобальный метод расширения, а SubmitChanges - это объект DataContext, который является объектом System.Data.Linq.DataContext.
LP добавляет только Dump и Disassemble, насколько мне известно. Хотя я бы настоятельно рекомендовал открыть его в Reflector, чтобы узнать, что еще можно использовать. Одним из наиболее интересных вопросов является пространство имен LINQPad.Util, которое имеет некоторые свойства, используемые LINQPad внутри.