Методи LINQPad [розширення]


144

Хтось має повний перелік методів та методів розширення LINQPad, таких як

.Dump()

SubmitChanges()

1
Я голосую за те, щоб закрити це питання поза темою, оскільки LINQPad - це інструмент, що постійно змінюється, а твердий, конкретний і остаточний відповідь на це питання матиме дуже короткий термін. Я пропоную закрити це як поза тему, щоб уникнути реклами подібних питань для інших інструментів.
Лассе В. Карлсен

5
Не те, що я маю що сказати про голосування, але я, безумовно, не згоден із закриттям цієї відповіді. Спочатку просто подивіться на резюме питання, а потім подивіться на результати перших двох коментарів. По-друге, як відповіді Йосифа можуть бути меншими, ніж остаточна відповідь; він написав річ. Нарешті, інші програми використовують Stackoverflow для своєї документації. Я весь час використовую LinqPad для розробки, прототипування запитів на C # і Linq, запуску SQL, виконання швидких завдань DBA та десятки інших речей. Тож, принаймні для мене, відповіді, безумовно, на тему.
EoRaptor013

3
Закриття: Я додав більше ніж одну відповідь на старіші запитання на C #, щоб забезпечити більш сучасну техніку, яка була введена мовою з моменту відповіді на запитання. ІМО, ми повинні очікувати, що база знань, представлених на цьому веб-сайті, змінюється та оновлюється в міру просування технологій. Спектр тем, де майбутні оновлення можуть поставити під загрозу чи скасувати відповіді, надані в певний момент часу, досить широкий: якби ми закрили всі питання, де це може статися, Переповнення стека було б набагато біднішим ресурсом! Тут повний список може стати частковим списком, який краще, ніж жоден список!
Боб Саммерс

Відповіді:


255

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's Dump ()
  • SqlOutputWriter - повертає текстовий записувач, який записує, у вікно виводу SQL
  • GetMyQueries , GetSamples - повертає колекцію об'єктів, що представляють ваші збережені запити / зразки (наприклад, виконайте пошук за допомогою редагування | Пошук всіх)
  • Виділити - загортає об’єкт, щоб він підсвічувався жовтим кольором при скиданні
  • 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);
}

33
Нічого кращого, ніж відповідь від самого автора!
Іван

1
Джо, я насправді хотів також прообразувати деякі графічні роботи, а потім хотів скинути растрову карту; Це було б чудово з методом Show для подібного роду робіт, де вам потрібна візуалізація, робота над графікою, зображенням тощо. Можливо, надання чітких візуалізацій для деяких інших типів вниз.
Бент Расмуссен

... Насправді, доки ви можете надсилати графіку на вихідну панель, ми можемо самі будувати розширення для решти.
Бент Расмуссен

3
Бета-версія 4,26 дозволяє вводити XHTML у вихідний потік, зателефонувавши до Util.RawHtml. Перейдіть на www.linqpad.net/beta.aspx (або зачекайте кілька днів на RTM).
Джо Альбахарі

1
Alex - щоб дістати> 1 річ на лінію, скористайся Util.HorizontalRun
Джо Альбахарі

131

Крім відомої 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 [string] - надає опис для скидання об'єкта
  • depth [int?] - обмежує глибину обстеження предметів рекурсивно
  • toDataGrid [bool] - якщо вірно, вихід буде форматований як сітка даних, а не як 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();

Примітка: Для отримання 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()використати метод розширення , будь ласка, перейдіть за цим посиланням на 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");
}

Це дозволяє перевірити, чи сценарій запускався з GUI LinqPad або через lprun.exeабо з Util.Run.

Примітка . Наступні варіанти виклику можуть бути корисними:

Util.Run(path+"foo.linq", dummy).Dump(); // obviously dumps the script output!
Util.Run(path+"foo.linq", dummy).Save(path+"foo.log"); // writes output into log
Util.Run(path+"foo.linq", dummy).SaveAsync(path+"foo1.log");     // async output log

SubmitChanges () - Зв'язок з 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 , ви також можете змінити постійні зміни (для операцій вставлення / оновлення / видалення ). Оскільки контекст бази даних неявно зроблений LinqPad, вам потрібно дзвонити SaveChanges()після кожної зміни, як показано нижче.

Приклади в основному такі ж, як і раніше для LinqToSQL , але вам потрібно скористатися SaveChanges()замість цього, а також для вставки та видалення методів змінилося.

Вставити

var newP = new Products() { ProductID=pID, CategoryID=cID, 
            ProductName="Salmon#"+pID.ToString() };
Products.Add(newP);
SaveChanges();  

Оновлення

var prod=(from p in Products
            where p.ProductName.Contains("Salmon")
            select p).FirstOrDefault();
prod.ProductName="Trout#"+prod.ProductID.ToString();
SaveChanges(); 

Видалити

var itemsToDelete=Products.Where(p=> p.ProductName.Contains("Salmon") ||
    p.ProductName.Contains("Trout"));
foreach(var item in itemsToDelete) { Products.Remove(item); }
SaveChanges();

Примітка. Щоб отримати дійсні ідентифікатори для попередніх прикладів, ви можете використовувати:

var cID = (from c in Categories 
            where c.CategoryName.Contains("Seafood") 
            select c).FirstOrDefault().CategoryID;

var pID = Products.Count()+1;

перш ніж викликати їх.


це - контекст бази даних

У LINQPad , то контекст бази даних застосовуються автоматично за допомогою випадаючого в верхньому і вибрати правильну базу даних для вашого запиту. Але іноді корисно посилатися на нього явно, наприклад, якщо ви скопіюєте якийсь код із свого проекту з Visual Studio і вставите його в LinqPad.

Ваш фрагмент коду, взятий з проекту Visual Studio, швидше за все, виглядає приблизно так:

var prod=(from p in dc.Products
            where p.ProductName.Contains("Salmon")
            select p).FirstOrDefault();
prod.ProductName="Trout#"+prod.ProductID.ToString();
dc.SaveChanges(); 

Тепер що робити dc? Звичайно, ви можете видалити кожне виникнення dc.запиту, але це набагато простіше. Просто додайте

var dc=this; // 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(); 
}   

і код запрацює миттєво!


це. Зв'язок

Використання 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 для запуску цього прикладу.

Примітка: Якщо ви просто хочете отримати базу даних та сервер поточного обраного з'єднання, ви можете використовувати цей фрагмент коду:

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

Ще один приклад: припустимо, що ваша DBA дає вам запит 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.
Звичайно, це спрощений приклад, ваша DBA, ймовірно, дасть вам складніший сценарій, але ви отримуєте ідею: Просто додайте підтримуючий результат результату, який містить усі поля з пункту 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);
}

Це створить наступну графіку (елементи панелі "Графіка" та "Малюнок" додаються прикладами вище):

Показ_Graphic_in_LinqPad

Якщо ви хочете відобразити зображення з бази даних Northwind, ви можете зробити наступне:
Змініть ім'я файлу зображення на "NorthwindPics.jpg", а потім додайте наступний код на початку методу Main () другого прикладу :

var img = (from e in this.Employees select e).FirstOrDefault().Photo.ToArray();
using (FileStream fs1 = new FileStream(pathImg, FileMode.Create))
{
    const int offset=78;
    fs1.Write(img, offset, img.Length-offset);
    fs1.Close();
}

Він прочитає перший запис із таблиці співробітників та відобразить малюнок.

Перегляньте наступні посилання, щоб дізнатися більше:
Фігури та основний малюнок у спеціалізованих візуалізаторах 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

Намалюйте графіку на 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> ("Введіть трохи json"); Раніше я копіював його у файл, а потім читав звідти ... Мені дуже подобається ця порада. Дякую!
loneshark99

2

Дамп - це глобальний метод розширення, і SubmitChanges походить від об'єкта DataContext, який є об'єктом System.Data.Linq.DataContext.

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


Примітка. У нових версіях LinqPad: натисніть .Dump()або будь-який інший метод у вихідному редакторі, натисніть F12, щоб "відобразити". Це тепер вбудовано в інструмент!
Метт

1

Досягнуто ліміту тексту StackOverflow в моїй попередній відповіді , але в LinqPad є ще більш круті розширення. Одну з них я хотів би зазначити:


Функції JavaScript (за допомогою .Dump())

З версії 5.42 бета-версії LinqPad ви можете вбудовувати функції 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.";
}

DumpContainerAnimation

Зауважте, що для деяких більш складних об'єктів, можливо, вам доведеться використовувати, 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.


Якщо я дізнаюся більше, я оновлю цю відповідь

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.