LINQPad [расширение] методы

У кого-нибудь есть полный список методов и методов расширения LINQPad, таких как

.Dump()

SubmitChanges()

3 ответа

Решение

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 есть несколько полезных статических методов. Они задокументированы в автозаполнении и включают в себя:

  • Cmd - выполняет команду оболочки или внешнюю программу
  • CreateXhtmlWriter - создает средство записи текста, использующее средство форматирования Dump () LINQPad
  • SqlOutputWriter - возвращает средство записи текста, которое пишет в окно вывода SQL
  • GetMyQueries, GetSamples - возвращает коллекцию объектов, представляющих ваши сохраненные запросы / примеры (например, выполнить поиск, используя Edit | Search All)
  • Подсветка - оборачивает объект так, что он будет выделяться желтым цветом при сбросе
  • HorizontalRun - позволяет вывести серию объектов на одной линии

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://stackru.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) были введены новые классы и методы:

  • DumpContainer (класс)
  • OnDemand (метод расширения)
  • Util.ProgressBar (класс)

Кроме того, класс 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.

И в заключение я покажу вам, как вы можете создать простую 2 -мерную графику внутри 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 -й пример делает обратное (обратите внимание, что он указывает только 2 из доступных параметров). Переменные y а также z не могут быть скрыты индивидуально, потому что они не на верхнем уровне.

Доступны следующие параметры (все являются необязательными):

  • description [строка] - предоставляет описание объекта для дампа
  • depth [int?] - ограничивает, насколько глубоко объекты рекурсивно проверяются
  • toDataGrid [bool] - если true, вывод форматируется как сетка данных, а не как RichText
  • exclude [строка] - если вы предоставите список переменных через запятую, они будут исключены из вывода (в примере "a,c": b а также d показаны, a а также c скрыты)
  • exclude [строка] с префиксом "+" - префикс инвертирует логику параметра исключения. Это означает, что если вы предоставите список переменных через запятую, все, кроме указанных, будут скрыты (в примере "+b,d": b а также d показаны, все остальные скрыты)
  • хранить включенные и исключенные свойства в переменной (впервые с LinqPad V5.09.04):
    var x=Util.ToExpando(obj, "a, c", "b, d"); x.Dump();
    Первая строка содержит список свойств, которые нужно включить, вторая строка - список исключаемых
  • развернуть по клику: если вы используете .OnDemand("click me").Dump(); вместо .Dump(), он будет отображать ссылку, которую вы можете нажать, чтобы развернуть. Полезно, если вы хотите проверить значения, например, Util.OnDemand("Customer-ID: " + customerObject.ID.ToString(), ()=>customerObject, false).Dump(); всегда показывать идентификатор по умолчанию, но раскрывать детали customerObject только если вы заинтересованы

Более сложные темы о дампе можно найти здесь.


Среда

Это не расширение LinqPad, а скорее класс.NET, но, поскольку оно полезно, я все равно упомяну об этом. Вы можете получить много полезной информации, которую можете использовать в своих скриптах, например:

Environment.UserDomainName.Dump();
Environment.MachineName.Dump();
Environment.UserName.Dump();
Environment.CurrentDirectory.Dump();
Environment.SystemDirectory.Dump();

NB Для получения Domain\UserName я хотел бы использовать System.Security.Principal.WindowsIdentity.GetCurrent().Name
скорее, чем Environment.UserDomainName+@"\"+Environment.UserName,


Util.WriteCsv

(новое: доступно начиная с версии LinqPad v4.45.05 (бета))

Util.WriteCsv (Customers, @"c:\temp\customers.csv");

Это напишет содержание таблицы Customers в файл CSV c:\temp\customers.csv, Вы также можете найти хороший пример, как использовать Util.WriteCsv а затем отобразить данные CSV в окне результатов Linqpad здесь.

подсказки:

  • Чтобы получить / создать файл CSV, который находится в том же каталоге, что и запрос, вы можете использовать:
    var csvFile=Util.CurrentQueryPath.Replace(".linq", ".csv");

  • Если таблица большая, используйте ObjectTrackingEnabled = false; прежде чем писать CSV, чтобы избежать кеширования в памяти.

  • Если вы хотите вывести таблицу в формате XML, а не в виде файла, разделенного запятыми, вы можете сделать это следующим образом:

    var xmlFile=Util.CurrentQueryPath.Replace(".linq", ".xml");
    var xml = XElement.Load(xmlFile);
    var query =
      from e in xml.Elements()
      where e.Attribute("attr1").Value == "a"
      select e;
    query.Dump();
    

    Этот пример возвращает все элементы, имеющие атрибут attr1 который содержит значение "a" из файла XML, имя которого совпадает с именем запроса и содержится в том же пути. Проверьте эту ссылку для большего количества примеров кода.


Util.GetPassword

var pwd = Util.GetPassword("UserXY");

Это восстановит пароль из встроенного в LinqPad менеджера паролей. Чтобы создать и изменить пароль, откройте пункт меню "Менеджер паролей" в меню "Файл" LinqPad. Если при запуске кода C# такой пароль не был сохранен, откроется диалоговое окно с запросом пароля, и у вас есть возможность создать и сохранить его на лету, установив флажок " Сохранить пароль" (в этом примере пароль для "UserXY" будет сохранен, и позже вы можете найти эту запись в Менеджере паролей).

Преимущества в том, что вы можете хранить пароль в LinqScripts, который вы создаете безопасно, отдельно и зашифрованы в профиле пользователя Windows (он хранится в %localappdata%\LINQPad\Passwords как файл). LinqPad использует Windows DPAPI для защиты пароля.

Кроме того, пароль хранится централизованно, поэтому, если вам нужно изменить его, вы можете сделать это в меню, и оно сразу же будет применено ко всем созданным вами сценариям.

Заметки:

  • Если вы не хотите сохранять пароль и просто вызывать диалоговое окно ввода пароля, вы можете использовать второй параметр следующим образом:
    var pwd = Util.GetPassword("UserXY", true);
    При этом флажок сохранения пароля будет снят в диалоговом окне ввода пароля (однако пользователь все равно может проверить его и в любом случае выбрать сохранение).

  • Если вам требуется, чтобы пароль был сохранен в SecureString, вы можете использовать эту вспомогательную функцию (nb: чтобы получить метод расширения .ToSecureString() используется, пожалуйста, перейдите по этой ссылке в Stackru - он также позволяет конвертировать его обратно при необходимости):
    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.HorizontRun

Вы можете использовать этот пример функции

public void ShowUrl(string strURL, string Title)
{
    Action showURL = delegate() { Process.Start("iexplore.exe", strURL); };
    var url = new Hyperlinq(showURL, "this link", true);
    Util.HorizontalRun (true, "Click ", url, " for details.").Dump(Title);
}

показывать гиперссылки в окне результатов - или любые действия, такие как открытие вашего любимого редактора. Использование:

ShowUrl("http://stackru.com", "Check out Stackru");

Обратите внимание, что эта функция всегда работает, а 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>&lt;RuntimeDirectory&gt;\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

Если вам нужно очистить окно результатов внутри скрипта, используйте:

Util.ClearResults();

Либо используйте его в начале вашего скрипта, либо - если вы выполняете несколько запросов в скрипте - вам следует подождать ввода данных пользователем, прежде чем закрыть экран (например, перед ним Util.ReadLine).


Custom.Dump () - ICustomMemberProvider

Также интересно то, что вы можете влиять на выход .Dump() метод. Просто реализуй интерфейс ICustomMemberProvider например,

public class test : ICustomMemberProvider 
{

      IEnumerable<string> ICustomMemberProvider.GetNames() {
        return new List<string>{"Hint", "constMember1", "constMember2", "myprop"};
      }

      IEnumerable<Type> ICustomMemberProvider.GetTypes() 
      {
        return new List<Type>{typeof(string), typeof(string[]), 
            typeof(string), typeof(string)};
      }

      IEnumerable<object> ICustomMemberProvider.GetValues() 
      {
        return new List<object>{
        "This class contains custom properties for .Dump()", 
        new string[]{"A", "B", "C"}, "blabla", abc};
      }

      public string abc = "Hello1"; // abc is shown as "myprop"
      public string xyz = "Hello2"; // xyz is entirely hidden
}

Если вы создаете экземпляр этого класса, как

var obj1 = new test();
obj1.Dump("Test");

тогда будет выводиться только Hint, constMember1, constMember2, а также myprop, но не собственность xyz:

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 из вашего скрипта или из вашей собственной программы.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 с Linq.

Еще один пример: предположим, что ваш администратор базы данных дает вам запрос SQL, и вы хотите проанализировать результаты в LinqPad - конечно, в Linq, а не в SQL. Тогда вы можете сделать следующее:

void Main()
{
    var dc=this;

    // do the SQL query
    var cmd =
        "SELECT Orders.OrderID, Orders.CustomerID, Customers.CompanyName,"
        +"       Customers.Address, Customers.City"
        +" FROM Customers INNER JOIN Orders ON Customers.CustomerID = Orders.CustomerID";
    var results = dc.ExecuteQuery<OrderResult>(cmd);

    // just get the cities back, ordered ascending
    results.Select(x=>x.City).Distinct().OrderBy(x=>x).Dump();
}

class OrderResult
{   // put here all the fields you're returning from the SELECT
    public dynamic OrderID=null; 
    public dynamic CustomerID=null;
    public dynamic CompanyName=null;
    public dynamic Address=null;
    public dynamic City=null;
}

В этом примере запрос SELECT DBA просто "добавляется" в текст команды, а результаты фильтруются и упорядочиваются по City.
Конечно, это упрощенный пример, ваш администратор базы данных, вероятно, поддержит вас более сложным сценарием, но у вас есть идея: просто добавьте вспомогательный класс результата, который содержит все поля из предложения SELECT, и вы можете напрямую использовать Это.
Таким образом, вы даже можете получить результат из хранимой процедуры и использовать его в Linq. Как видите, в этом примере меня не интересует тип данных и их использование. dynamic чтобы выразить это.
Так что это действительно быстрое программирование, чтобы иметь возможность быстро анализировать данные. Вы не должны делать это в вашем реальном приложении по разным причинам (SQL-инъекция, потому что вы можете использовать EF с самого начала и т. Д.).


PanelManager

Рисуем графику в LinqPad, часть 1

Чтобы использовать примеры ниже, нажмите F4 и добавьте System.Windows.dll, System.Windows.Forms.dll, WindowsFormsIntegration.dll, PresentationCore.dll а также PresentationFramework.dll к вашей программе LinqPad, а также добавить пространство имен System.Windows.Shapes,

Первый пример просто рисует линию:

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)
{
    // https://stackru.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);
}

Это создаст следующую графику (элементы панели "Графика" и "Рисунок" добавлены примерами выше):

Showing_Graphic_in_LinqPad

Если вы хотите отобразить изображения из базы данных 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() способ включить тесты для ваших расширений.

В моем предыдущем ответе достигнут предел текста Stackru, но в LinqPad есть еще более интересные расширения. Об одном из них хотелось бы упомянуть:


Функции 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 ниже). Это можно сделать с помощью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. Он доступен через поддержку NUGET LinqPad - через F4- в диалоговом окне Add NUGET..... Вот пошаговое описание того, как использовать xUnit с LinqPad V5 или V6.


Если я узнаю больше, я обновлю этот ответ

Дамп - это метод глобального расширения, а SubmitChanges происходит из объекта DataContext, который является объектом System.Data.Linq.DataContext.

Насколько мне известно, LP добавляет только Dump и Disassemble. Хотя я очень рекомендую открыть его в Reflector, чтобы увидеть, что еще можно использовать. Одна из наиболее интересных вещей - это пространство имен LINQPad.Util, в котором есть некоторые полезности, используемые LINQPad для внутренних целей.

Другие вопросы по тегам