LINQPad [扩展]方法

时间:2010-08-24 09:59:41

标签: c# .net entity-framework linq-to-sql linqpad

有没有人有完整的LINQPad扩展方法和方法列表,例如

.Dump()

SubmitChanges()

3 个答案:

答案 0 :(得分:232)

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 - 执行shell命令或外部程序
  • CreateXhtmlWriter - 创建一个使用LINQPad的Dump()格式化程序的文本编写器
  • SqlOutputWriter - 返回写入SQL输出窗口的文本编写器
  • GetMyQueries GetSamples - 返回表示已保存查询/示例的对象集合(例如,使用“编辑”|“全部搜索”执行搜索)
  • 突出显示 - 包装对象,以便在倾倒时以黄色突出显示
  • Horizo​​ntalRun - 允许您在同一行上转储一系列对象

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();

结果:

  

查看this site以获取编程问题的答案。

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)new classes and methods have been introduced中:

  • DumpContainer(class)
  • OnDemand(扩展方法)
  • Util.ProgressBar(class)

此外,Hyperlinq类现在支持Action委托,当您单击链接时将调用该委托,允许您在代码中对其作出反应,而不仅仅是链接到外部网页。

DumpContainer是一个类,它可以在输出窗口中添加一个可以替换其内容的块。

注意!请记住.Dump() DumpContainer本身在适当的位置。

使用:

var dc = new DumpContainer();
dc.Content = "Test";
// further down in the code
dc.Content = "Another test";

OnDemand是一种扩展方法,它不会将其参数的内容输出到输出窗口,而是添加一个可点击的链接,单击此链接将替换带有.Dump() ed内容的链接。参数。这对于有时需要的数据结构非常有用,这些数据结构成本高昂或占用大量空间。

注意!请记住.Dump()在适当位置调用OnDemand的结果。

使用它:

Customers.OnDemand("Customers").Dump(); // description is optional

Util.ProgressBar是一个可以在输出窗口中显示图形进度条的类,可以在代码移动时更改。

注意!请记住.Dump()适当位置的Util.ProgressBar对象。

使用它:

var pb = new Util.ProgressBar("Analyzing data");
pb.Dump();
for (int index = 0; index <= 100; index++)
{
    pb.Percent = index;
    Thread.Sleep(100);
}

答案 1 :(得分:2)

Dump是一个全局扩展方法,SubmitChanges来自DataContext对象,它是一个System.Data.Linq.DataContext对象。

据我所知,LP只添加了Dump和Disassemble。虽然我强烈建议在Reflector中打开它,看看还有什么可以使用。其中一个更有趣的事情是LINQPad.Util命名空间,它内部有一些LINQPad使用的好东西。

答案 2 :(得分:2)

在我的previous answer中达到了 StackOverflow文本限制,但是LinqPad中仍然有更多很棒的扩展。我想提及其中之一:


在LinqPad中编写自己的扩展名

列表表

您知道您可以在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();
    }
}

Joe(LinqPad的作者)向我提供了此片段-它说明了如何将数据上下文传递给“我的扩展程序”。

通过以下方式使用此扩展名:在LinqPad中打开一个新的C#查询窗口(使用 Ctrl + N ),然后连接到您选择的数据库,然后键入:

新查询

void Main()
{
    this.ListTables();
}

重要提示:如果您未连接到数据库,则该扩展名不可用,LinqPad将显示错误。因此,请先连接到数据库,然后键入this.ListTables();

请注意,IntelliSense将显示我们在“我的扩展”中键入的XML注释的摘要。运行它之后,您将获得当前数据库表的列表。

JavaScript函数(使用.Dump()

从LinqPad的版本 5.42 beta 开始,您可以嵌入JavaScript函数并直接从C#代码中调用它们。尽管有一些限制(与JSFiddle相比),但这是在LinqPad中快速测试一些JavaScript代码的好方法。

示例:

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;-))。

另一种选择,如果您喜欢Lambda表达式,并且不想每次调用时都将函数名称指定为字符串,则可以执行以下操作:

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函数本身的名称相同(请注意,如何使用lambda表达式来解析变量名,这不能通过使用{{ 1}})。


.Dump()-内联更新消息

有时候,覆盖转储的文本很有用,而不是将其放在新行中,例如,如果您正在执行长时间运行的查询并希望显示其进度等(请参阅还有下面的ProgressBar)。这可以通过使用nameof(paramName)完成,您可以按照

所示使用它

示例1:

DumpContainer

DumpContainerAnimation

请注意,对于某些更复杂的对象,您可能必须使用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);

示例2:

dc.Content=...

Util.ProgressBar

也可以通过使用ProgressBar来显示进度,如下所示:

示例:

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!");
}

这与之前的转储示例相似,但是这次显示了一个不错的进度条动画。


使用LinqPad-xUnit进行单元测试

您知道您可以在LinqPad中编写单元测试吗?例如,您可以使用xUnit框架。它可以通过LinqPad的NUGET支持获得-通过 F4 -在对话框中单击 Add NUGET .... 。这是逐步说明 use xUnit with LinqPad V5 or V6.


如果我发现更多,我将更新此答案