Есть ли у кого-нибудь полный список методов и методов расширения LINQPad, таких как
.Dump()
SubmitChanges()
c#
.net
entity-framework
linq-to-sql
linqpad
Бент Расмуссен
источник
источник
Ответы:
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 (из моего собственного опыта работы с инструментом):
.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
[строка] - описание объекта для дампа.depth
[int?] - ограничивает глубину рекурсивной проверки объектов.toDataGrid
[bool] - если true, вывод форматируется как datagrid, а не как RichTextexclude
[строка] - если вы предоставите разделенный запятыми список переменных, они будут исключены из вывода (в примере «а, с»: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
только в том случае, если вас это интересует.Здесь и там можно найти более сложные темы о Dump .
Окружающая среда
Это не расширение LinqPad, а класс .NET, но, поскольку он полезен, я все равно упомяну его. Вы можете получить много полезной информации, которую можете использовать в своих скриптах, например:
NB Для получения
Domain\UserName
я быSystem.Security.Principal.WindowsIdentity.GetCurrent().Name
скорее использовал чем
Environment.UserDomainName+@"\"+Environment.UserName
.Util.WriteCsv
( новое: доступно, начиная с версии LinqPad v4.45.05 (бета) )
Util.WriteCsv (Customers, @"c:\temp\customers.csv");
Это запишет содержимое таблицы
Customers
в файл CSVc:\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 # пароль не сохранен, откроется диалоговое окно с запросом пароля, и у вас есть возможность создать и сохранить его на лету, установив флажок сохранения пароля (в примере пароль для "UserXY" будет сохранен, и позже вы можете найти эту запись в диспетчере паролей ).
Преимущества заключаются в том, что вы можете безопасно хранить пароль в создаваемых вами сценариях LinqScripts, отдельно и в зашифрованном виде в профиле пользователя Windows (он хранится в
%localappdata%\LINQPad\Passwords
виде файла). LinqPad использует Windows DPAPI для защиты пароля.Кроме того, пароль хранится централизованно, поэтому, если вам нужно его изменить, вы можете сделать это в меню, и он немедленно применяется ко всем созданным вами скриптам.
Примечания:
Если вы не хотите сохранять пароль, а просто вызываете диалоговое окно пароля, вы можете использовать второй параметр следующим образом:
var pwd = Util.GetPassword("UserXY", true);
Это снимет флажок сохранения пароля в диалоговом окне пароля (однако пользователь все еще может проверить его и все равно выберите сохранение).
Если вам требуется, чтобы пароль сохранялся в a
SecureString
, вы можете использовать эту вспомогательную функцию (nb: чтобы получить используемый метод расширения.ToSecureString()
, перейдите по этой ссылке в Stackoverflow - он также позволяет вам преобразовать его обратно, если это необходимо):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 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.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.Util.ClearResults
Если вам нужно очистить окно результатов внутри вашего скрипта, используйте:
Либо используйте его в верхней части сценария, либо - если вы выполняете несколько запросов в сценарии - вы должны дождаться ввода пользователя перед тем, как очистить экран (например, поставив перед ним значок
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
:Отображение 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 из вашего сценария или из вашей собственной программы .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 :
Вставить
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 , то контекст базы данных применяются автоматически с помощью выпадающего в верхнем и выбрать правильную базу данных для вашего запроса. Но иногда полезно ссылаться на него явно, например, если вы копируете код из своего проекта из 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, чтобы запустить этот пример.
NB: Если вы просто хотите получить базу данных и сервер для текущего выбранного соединения, вы можете использовать этот фрагмент кода:
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 dynamic с 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 просто «вставлен» в текст команды, а результаты фильтруются и упорядочиваются по городу.
Конечно, это упрощенный пример, ваш администратор баз данных, вероятно, предоставит вам более сложный сценарий, но вы поняли идею: просто добавьте вспомогательный класс результатов, который содержит все поля из предложения 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
.Первый пример просто рисует линию:
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 () 2-го примера :
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 Форум также содержит полезные советы.Также очень полезно: эта статья об отладке 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 и Disassemble. Хотя я настоятельно рекомендую открыть его в Reflector, чтобы посмотреть, что еще можно использовать. Одна из наиболее интересных вещей - это пространство имен LINQPad.Util, в котором есть некоторые полезности, используемые LINQPad внутри.
источник
.Dump()
или любой другой метод в редакторе исходного кода, нажмите F12, чтобы «отразить». Теперь это встроено в инструмент!В моем предыдущем ответе достигнут предел текста StackOverflow , но в LinqPad есть еще более интересные расширения. Об одном из них хотелось бы упомянуть:
Напишите свои собственные расширения в LinqPad
ListTables
Знаете ли вы, что в LinqPad можно писать собственные расширения, доступные для всех запросов? Вот как это можно сделать: в LinqPad перейдите на вкладку «Мои запросы» с левой стороны, прокрутите вниз до конца, пока не увидите «Мои расширения». Дважды щелкните по нему, и откроется специальное окно запроса с именем Мои расширения. То, что вы там напишете, станет доступно во всех запросах.
Теперь вставьте в него следующий код и сохраните его с помощью Ctrl+ S:
Мои расширения
void Main() { // no code here, but Main() must exist } public static class MyExtensions { /// <summary> /// This will list the tables of the connected database /// </summary> public static void ListTables(this System.Data.Linq.DataContext dc) { var query = dc.Mapping.GetTables(); query.Select(t => t.TableName).OrderBy(o => o).Dump(); } }
Джо (автор LinqPad) любезно предоставил мне этот фрагмент - он показывает, как вы можете передать контекст данных в Мои расширения.
Используйте это расширение следующим образом: откройте новое окно запроса C # в LinqPad (с помощью Ctrl+ N), затем подключитесь к базе данных по вашему выбору и введите:
Новый запрос
void Main() { this.ListTables(); }
Важно: если вы не подключены к базе данных, значит, расширение недоступно, и LinqPad покажет ошибку. Итак, сначала подключитесь к базе данных, затем введите
this.ListTables();
.Обратите внимание, что IntelliSense покажет сводку XML-комментария, который мы ввели в «Мои расширения». После запуска вы получите список таблиц текущей базы данных.
Функции JavaScript (с использованием
.Dump()
)Начиная с бета-версии LinqPad 5.42 вы можете встраивать функции 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)
внутри функции)..Dump () - обновление сообщения в строке
Иногда полезно перезаписать скопированный текст вместо того, чтобы помещать его в новую строку, например, если вы выполняете длительный запрос и хотите показать его прогресс и т. Д. (См. Также 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!"); }
Util.ProgressBar
Отображение прогресса также можно выполнить с помощью 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
Знаете ли вы, что в LinqPad можно писать модульные тесты? Например, вы можете использовать фреймворк xUnit. Он доступен через поддержку LinqPad NUGET - через F4- в диалоговом окне Add NUGET..... Вот пошаговое описание того, как использовать xUnit с LinqPad V5 или V6.
Если я узнаю больше, я обновлю этот ответ
источник