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

146

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

.Dump()

SubmitChanges()
Бент Расмуссен
источник
1
Я голосую за то, чтобы закрыть этот вопрос как не по теме, потому что LINQPad - это постоянно меняющийся инструмент, и имея твердый, конкретный и окончательный ответ на этот вопрос, будет очень недолго. Предлагаю закрыть его как не по теме, чтобы не задавать подобные вопросы другим инструментам.
Лассе В. Карлсен
5
Не то чтобы мне было что сказать о голосовании, но я определенно не согласен с завершением этого ответа. Сначала просто посмотрите на голоса за вопрос, а затем посмотрите на первые два комментария. Во-вторых, как ответы Джозефа могут быть меньше окончательного ответа; он написал эту вещь. Наконец, другие приложения используют Stackoverflow для своей документации. Я все время использую LinqPad для разработки, создания прототипов запросов C # и Linq, выполнения SQL и выполнения задач быстрого администратора баз данных и множества других вещей. Так что, по крайней мере для меня, ответы определенно по теме.
EoRaptor013
3
В заключение: я добавил более одного ответа на старые вопросы по C #, чтобы предоставить более современную технику, которая была введена в язык после того, как был дан ответ на вопрос. ИМО, мы должны ожидать, что база знаний, которую представляет этот сайт, будет изменяться и обновляться по мере развития технологий. Диапазон тем, в которых будущие обновления могут скомпрометировать или аннулировать ответы, данные в определенный момент времени, довольно широк: если мы закроем все вопросы, где это могло произойти, Stack Overflow был бы гораздо более бедным ресурсом! Здесь полный список может превратиться в неполный список, что лучше, чем отсутствие списка!
Боб

Ответы:

257

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 - создает средство записи текста, использующее средство форматирования LINQPad Dump ().
  • 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://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) были введены новые классы и методы :

  • 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);
}
Джо Альбахари
источник
34
Нет ничего лучше ответа самого автора!
Джон
1
Джо, на самом деле я хотел создать прототип для графической работы, а затем хотел выгрузить растровое изображение; Было бы здорово использовать метод Show для такого рода работы, где вам нужна визуализация, работа с графикой, изображением и т. д. Возможно предоставление аккуратных визуализаций для некоторых других типов в будущем.
Бент Расмуссен
... На самом деле, если вы можете отправлять графику на панель вывода, мы можем сами создавать расширения для остальных.
Бент Расмуссен
3
Бета-версия 4.26 позволяет вводить XHTML в выходной поток, вызывая Util.RawHtml. Перейдите на сайт www.linqpad.net/beta.aspx (или подождите несколько дней, пока не появится RTM).
Джо Альбахари
1
Alex - чтобы поставить> 1 вещь на линию, используйте Util.HorizontalRun
Джо Альбахари
133

Помимо хорошо известного 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, а не как RichText
  • exclude[строка] - если вы предоставите разделенный запятыми список переменных, они будут исключены из вывода (в примере «а, с»: bи dпоказаны, aи cскрыты)
  • exclude[строка] с префиксом "+" - префикс инвертирует логику параметра исключения. Это означает, что если вы предоставите список переменных, разделенных запятыми, все, кроме указанных, будут скрыты (в примере "+ b, d": bи dпоказаны, все остальные скрыты)
  • хранить включенные и исключенные свойства в переменной (новое, начиная с LinqPad V5.09.04):
    var x=Util.ToExpando(obj, "a, c", "b, d"); x.Dump();
    первая строка содержит список свойств для включения, вторая строка - список для исключения
  • расширять при щелчке: если вы используете .OnDemand("click me").Dump();вместо .Dump(), будет отображаться ссылка, по которой вы можете щелкнуть, чтобы развернуть. Полезно, если вы хотите проверить значения, например, Util.OnDemand("Customer-ID: " + customerObject.ID.ToString(), ()=>customerObject, false).Dump();чтобы всегда показывать идентификатор по умолчанию, но раскрывать детали customerObjectтолько в том случае, если вас это интересует.

Здесь и там можно найти более сложные темы о Dump .


Окружающая среда

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

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

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


Util.WriteCsv

( новое: доступно, начиная с версии 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);
    Это снимет флажок сохранения пароля в диалоговом окне пароля (однако пользователь все еще может проверить его и все равно выберите сохранение).

  • Если вам требуется, чтобы пароль сохранялся в 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>&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).


Пользовательский .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


Отображение 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);
}

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

Отображение_графического_в_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.dllSystem.Windows.Forms.dllSystem.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()метод для включения тестов для ваших расширений.

Мэтт
источник
2
мне нравится совет об Util.ReadLine <string> ("Enter some json"); Раньше я копировал его в файл, а потом читал оттуда ... Мне очень нравится этот совет. Благодарность!
loneshark99
2

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

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

Джон
источник
Примечание. В более новых версиях LinqPad: щелкните .Dump()или любой другой метод в редакторе исходного кода, нажмите F12, чтобы «отразить». Теперь это встроено в инструмент!
Мэтт
1

В моем предыдущем ответе достигнут предел текста 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.


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

Мэтт
источник