windows LINQPad [extension]方法[已关闭]

but5z9lq  于 2023-08-07  发布在  Windows
关注(0)|答案(4)|浏览(95)

**已关闭。**此问题不符合Stack Overflow guidelines。它目前不接受回答。

这个问题似乎与a specific programming problem, a software algorithm, or software tools primarily used by programmers无关。如果您认为该问题与another Stack Exchange site上的主题相符,您可以发表评论,说明在何处可以回答该问题。
两年前关闭。
Improve this question
有人有LINQPad扩展方法和方法的完整列表吗,比如

.Dump()

SubmitChanges()

字符串

au9on6nz

au9on6nz1#

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. Utility中还有一些有用的静态方法。这些记录在自动完成中,包括:

*Cmd-执行shell命令或外部程序
*CreateXhtmlWriter-创建使用LINQPad的Dump()格式化程序的文本编写器
*SqlOutputWriter-返回写入SQL输出窗口的文本编写器
*GetMyQueriesGetSamples-返回表示已保存查询/样本的对象集合(例如,使用“编辑”执行搜索|搜索全部)
*高亮-包裹对象,使其在转储时高亮显示为黄色
*HorizontalRun-将一系列对象转储到同一行

LINQPad还提供了HyperLinq类。这有两个目的:第一种是显示普通超链接:

new Hyperlinq ("www.linqpad.net").Dump();
new Hyperlinq ("www.linqpad.net", "Web site").Dump();
new Hyperlinq ("mailto:user@domain.example", "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(类)

此外,Hyperlinq类现在支持Action委托,当您单击链接时将调用该委托,允许您在代码中对其做出React,而不仅仅是链接到外部网页。
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);
}

cbjzeqam

cbjzeqam2#

LinqPad扩展方法-第1部分,共2部分

Go to part 2
除了众所周知的myQuery.Dump("Query result:"),另一个要提到的特性是Util类:它包含许多非常方便的方法(我已经提到了其中的一些,但还有更多)。
同样有趣的是,您可以修改Dump()的工作方式
最后,我将向您展示如何使更改永久(即 * 插入,更新,删除 * LINQ查询)使用SubmitChanges()SaveChanges()以及如何访问LinqPad的内部连接对象。
最后,我将向您展示如何在LinqPad中创建简单的2D图形(绘制 * 线条、位图 * 或 * 函数 *)。
所以,这里有一个LinqPad内置功能的集合(来自我自己使用该工具的经验):

.Dump()

  • (LinqPad v5.03.08及以上版本中提供的参数)*

.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

字符串

  • 第1个示例 * 只打印变量ac,并隐藏bd,* 第2个示例 * 则相反(注意,它只指定了2个可用参数)。变量yz不能单独隐藏,因为它们不在顶层。

以下参数可用(均为可选):

  • description [string] -提供要转储的对象的描述
  • depth [int?] -限制递归检查对象的深度
  • toDataGrid [bool] -如果为true,则输出格式为数据网格而不是RichText
  • exclude [string] -如果您提供一个逗号分隔的变量列表,它们将从输出中排除(在示例“a,c”中:显示bd,隐藏ac
  • exclude [string] with“+”prefix -前缀反转exclude参数的逻辑。这意味着,如果您提供一个逗号分隔的变量列表,则除了指定的变量之外,所有变量都是隐藏的(在示例“+b,d”中:显示bd,所有其他隐藏)
  • 在变量中存储包含和排除的属性(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();总是默认显示ID,但仅在您感兴趣时才显示customerObject的详细信息。

有关转储的更多高级主题,请参见
here (Customizing Dump)there (Extensions Part 2)

Util.WriteCsv

(**新增:**自LinqPad version v4.45.05 (beta)起可用)

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


这将把表Customers的内容写入CSV文件c:\temp\customers.csv。您还可以找到一个很好的例子,如何使用Util.WriteCsv,然后在Linqpad的结果窗口here中显示CSV数据。

提示:

  • 要获取/创建与查询位于同一目录中的CSV文件,可以用途:

var csvFile=Util.CurrentQueryPath.Replace(".linq", ".csv");

  • 如果表很大,请在写入CSV之前使用ObjectTrackingEnabled = false;,以避免将其缓存在内存中。
  • 如果您想以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的所有元素,该属性包含XML文件中的值"a",该XML文件与查询同名并包含在同一路径中。查看this链接以获取更多代码示例。

Util.GetPassword

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


这将从LinqPad的内置密码管理器中检索密码。要创建和更改密码,请在LinqPad的**“文件”菜单中打开“密码管理器”菜单项**。如果在运行C#代码时没有保存密码,则会打开一个密码对话框,要求您输入密码,您可以选择通过选中 save password 复选框来动态创建和保存密码(在示例中,“UserXY”的密码将被保存,稍后您可以在密码管理器中找到此条目)。
优点是,您可以将密码存储在您创建的LinqScripts中,安全地、单独地存储在Windows用户配置文件中,并加密(它以文件形式存储在%localappdata%\LINQPad\Passwords中)。LinqPad使用Windows DPAPI来保护密码。
此外,密码是集中存储的,因此如果您需要更改它,您可以在菜单中进行更改,它会立即应用于您创建的所有脚本。

备注:

  • 如果你不想保存密码,而只是弹出一个密码对话框,你可以使用第二个参数如下:

var pwd = Util.GetPassword("UserXY", true);
这将取消选中密码对话框中的 * 保存密码 * 复选框(但是,用户仍然可以选中它并选择保存)。

  • 如果您需要将密码存储在SecureString中,则可以使用此帮助函数(注意:要获得使用的扩展方法.ToSecureString(),请按照this link at 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();


这将转储C:\windows\system32中包含的所有文件扩展名为“.exe”或“.dll”的文件。/s开关用于递归所有子目录,/b用于裸输出格式。请注意,Cmd方法的第二个参数被指定为禁止控制台输出,以便仅显示使用Dump方法筛选的结果。
您可以看到,这比dir中的通配符更灵活,因为您可以使用Linq查询引擎的全部灵活性。

示例2 -文本编辑器:

您可以在记事本中打开文件,如下所示:

var filePath=@"C:\HelloWorld.txt";
Util.Cmd(@"%systemroot%\system32\notepad.exe", filePath);

使用镜像

显示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可以显示进度条。你可以使用下面的helper类:

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


不同之处在于,它不会显示在结果窗口中,并且您不能为其分配消息。

使用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的一部分)。

实用程序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 。
x1c 0d1x的数据

实用工具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");


则只输出HintconstMember1constMember2myprop,而不输出属性xyz


在LinqPad中显示MessageBox或InputBox

如果你需要显示一个消息框,看看here如何做到这一点。
例如,可以使用以下代码显示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
    }
}


(don别忘了按F4并添加Microsoft.VisualBasic.dll及其命名空间以使其工作)

实用程序运行

(**新增:**自LinqPad version v4.52.1 (beta)起可用)
允许您从脚本或您自己的.NET程序或Windows服务中运行另一个LINQPad脚本(通过引用LINQPad.exe的LINQPad 4-AnyCPU版本)。它执行脚本的方式与命令行工具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 GUI内部运行的,还是通过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();

**注意:**为了获得前面示例中的有效ID,您可以用途:

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

**注意:**为了获得前面示例中的有效ID,您可以用途:

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

var pID = Products.Count()+1;

在你召唤他们之前。

如果你需要交易,看看这篇文章:How to nest transactions

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.,但这要容易得多。只需将其添加到代码片段的顶部,如下所示:

UserQuery dc { get => this; }
void Main()
{
    var prod=(from p in dc.Products
                where p.ProductName.Contains("Salmon")
                select p).FirstOrDefault();
    prod.ProductName="Trout#"+prod.ProductID.ToString();
    dc.SaveChanges(); 
}

代码将立即工作!

this.连接

使用LinqPad和OleDb,将数据表转换为Linq对象,在Linq中进行SQL查询

下面的代码片段可以帮助您将LinqPad与OleDb一起使用。将System.Data程序集中的System.Data.OleDb添加到查询属性中,然后将以下代码粘贴到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,**以下问题的答案显示了如何做到这一点:Nice examples of using .NET 4 dynamic keyword with 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;
}

在本例中,DBA的SELECT查询只是被“抛出”到命令文本中,结果按城市进行过滤和排序。
当然,这是一个简化的例子,你的DBA可能会给予你一个更复杂的脚本,但你已经明白了:添加一个包含SELECT子句中所有字段的支持结果类,然后可以直接使用它。
您甚至可以通过这种方式从存储过程中获取结果并在Linq中使用它。正如你所看到的,在这个例子中,我不关心数据类型,并使用dynamic来表达它。
所以这实际上是关于快速编程,以便能够快速分析数据。出于各种原因(SQL注入,因为您可以从一开始就使用EF等),您不应该在真实的应用程序中这样做。

面板管理器

在LinqPad中绘制图形,第1部分

要使用下面的示例,请按F4并将System.Windows.dllSystem.Windows.Forms.dllWindowsFormsIntegration.dllPresentationCore.dllPresentationFramework.dll添加到您的LinqPad程序中,并添加命名空间System.Windows.Shapes

    • 第1个示例**简单地画了一条线:
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");
    • 第二个示例**显示了如何使用PanelManager在LinqPad中显示图形。通常LinqPad只支持Wpf对象。这个例子使用System.Windows.Forms.Integration.WindowsFormsHost来使PictureBox可用(它的灵感来自this):
// needs (F4): System.Windows.dll, System.Windows.Forms.dll, 
// WindowsFormsIntegration.dll, PresentationCore.dll, PresentationFramework.dll 
void Main()
{       
    var wfHost1 = new System.Windows.Forms.Integration.WindowsFormsHost();
    wfHost1.Height=175; wfHost1.Width=175; wfHost1.Name="Picturebox1";
    wfHost1.HorizontalAlignment=System.Windows.HorizontalAlignment.Left;
    wfHost1.VerticalAlignment=System.Windows.VerticalAlignment.Top;
    System.Windows.Forms.PictureBox pBox1 = new System.Windows.Forms.PictureBox();
    wfHost1.Child = pBox1;
    pBox1.Paint += new System.Windows.Forms.PaintEventHandler(picturebox1_Paint);
    PanelManager.StackWpfElement(wfHost1, "Picture");
} 

public string pathImg
{
    get { return System.IO.Path.Combine(@"C:\Users\Public\Pictures\Sample Pictures\", 
            "Tulips.jpg"); } 
}

// Define other methods and classes here
public void picturebox1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
    // https://stackoverflow.com/a/14143574/1016343
    System.Drawing.Bitmap bmp = new System.Drawing.Bitmap(pathImg);
    System.Drawing.Point ulPoint = new System.Drawing.Point(0, 0);
    e.Graphics.DrawImage(bmp, ulPoint.X, ulPoint.Y, 175, 175);
}

这将创建以下图形(面板项“图形”和“图片”是通过上述示例添加的):



如果要显示Northwind数据库中的图像,可以执行以下操作:
将图片文件名改为“NorthwindPics.jpg”,然后在
第二个示例的
Main()方法的开头添加以下代码:

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

它将从Employees表中读取第一条记录并显示图片。
查看以下链接以了解更多信息:
Shapes and basic drawing in WPF
LinqPad custom visualizers

**注意:**您也可以在没有PanelManager的情况下实现相同的功能,如下面的示例所示,我看到here显示:

// 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部分

下面的示例受**this**帖子的启发,展示了如何使用C#7在Linqpad中实现函数绘图仪:

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
并添加这些程序集中的所有命名空间。

其他提示/进一步阅读:

  • 是否要在Visual Studio中使用LinqPad?这里是how you can do that
  • 需要将LinqPad作为**“便携式应用程序”**?Read here怎么做
  • 乔的LinqPad网站是一个很好的来源。在LinqPad中,Help -> What's New为您提供了有关新函数和方法的提示。LinqPad Forum还包含有用的提示。
  • 也很有用:This关于Linq(Pad)调试的文章。
  • 批处理脚本中使用lprun.exe进行LINQ查询**,**详情请阅读this article。举例来说:

echo Customers.Take(100) > script.txt
lprun -lang=e -cxname=CompanyServer.CustomerDb script.txt
在本例中,查询是一个简单的LINQ表达式。当然,您也可以使用-lang=program来激活程序模式,从而准备复杂的查询。

  • 您可以在LinqPad左手的【我的查询】选项卡中编写和存储扩展方法:树的最后一项名为我的扩展名;双击它打开一个文件,你可以在其中写入所有查询都可用的扩展名。将它们放入公共静态类MyExtensions中,并使用Main()方法来包含扩展的测试。

Continued here...

hivapdat

hivapdat3#

LinqPad扩展方法-第2部分(共2部分)

Go to part 1
在我的previous answer中达到了30000个字符的StackOverflow文本限制,但LinqPad中还有更多很酷的扩展。其中一些我想提一下:

自动滚屏等快捷方式

  • 查询运行时自动滚动结果窗口的末尾

(使用.Dump()语句):
Shift+Control+E切换(打开或关闭)

  • 多个入口点:
    Alt+Shift+1运行Main1()Alt+Shift+2运行Main2(),依此类推。
    注意您仍然需要void Main()作为主入口点,以上方法是附加(可选)入口点。
  • 运行xUnit测试:

Alt+Shift+T运行所有xUnit测试,使用[Fact][Theory]修饰
(as您需要通过Query -> Add xUnit test support菜单添加xUnit支持)

环境

这不是一个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

在LinqPad中编写自己的扩展

ListTables

你知道你可以在LinqPad中编写自己的扩展吗?以下是您的操作方法:在LinqPad中,转到左侧的“我的查询”选项卡,向下滚动到最后,直到看到“我的扩展”。双击它,它将打开一个名为My Extensions的特殊查询窗口。您在那里写的内容将在所有查询中可用。
现在将以下代码粘贴到其中,然后使用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 IOrderedEnumerable<string> ListTables(
                        this System.Data.Linq.DataContext dc, bool dumpIt = true)
    {
       var query = dc.Mapping.GetTables();
       var result = query.Select(t => t.TableName).OrderBy(o => o);
       if (dumpIt) result.Dump();
       return result;
    }
}


Joe(LinqPad的作者)好心地为我提供了这个片段--它展示了如何将数据上下文传递给My Extensions。

**注意:**对于LinqPad 6以上版本,查询属性需要按F4,勾选“引用LINQ-to-SQL程序集”才能生效。

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

  • 新查询 *
void Main()
{
    this.ListTables();
}

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

请注意,IntelliSense将显示我们在My Extensions中键入的XML注解的摘要。一旦你运行它,你将得到当前数据库的表列表。

LinqPad配置文件(appsettings.json)

之前我已经介绍了如何使用MyExtensions。现在,如果你想要一个全局appsettings.json文件,或者每个脚本一个,你可以使用以下扩展名:

public static class MyExtensions
{
    // needs: Microsoft.Extensions.Configuration.json, press F4 and add it as NUGET package
    public static IConfiguration AppSettings(string path = null)
    {
            IConfiguration config = null;
            var configFile = (path != null) ? path : Util.CurrentQueryPath.Replace(".linq", ".appsettings.json");
            if (System.IO.File.Exists(configFile))
            {
                var builder = new ConfigurationBuilder().AddJsonFile(configFile);
                config = builder.Build();
            }
            else
            {
                configFile.Dump("Not found");
            }
            return config;
    }
}


您也可以直接将其存储在C#程序中,但这种方式在默认情况下是可用的,并且您只需要执行一次NUGET加载。
假设你写了一个LinqPad程序"YourCSharpProgram.linq"。现在您可以提供如下配置

var config1 = MyExtensions.AppSettings();


或类似

var config2 = MyExtensions.AppSettings("C:\MyGlobalSettings\appsettings.json");


第一个选项,config 1,将期望在文件"YourCSharpProgram.linq"下的设置,并将"appsettings.json"附加到它,这意味着您的设置必须在与程序相同的文件夹中的"YourCSharpProgram.linq.appsettings.json"中。第二个选项只使用指定的绝对路径。
如果您的设置文件包含

{
    "AzureStorage": {
        "StorageConnectionString": "some connection string"
    }
}


你可以像

var config = MyExtensions.AppSettings();
string connectionString = config.GetSection("AzureStorage").GetSection("StorageConnectionString").Value.ToString();
connectionString.Dump();

**注意:**第二种使用配置的方法是将JSON文件的绝对路径放置在LinqPads F4对话框中。在LinqPad 5中,这更好,因为设置文件有一个单独的选项卡(它是AppConfig,因为版本5是针对.NET的,而不是.NET内核的)。您必须像使用程序集那样引用它,而且这并不明显。所以我更喜欢上面描述的。

.Dump()-重新访问

点击操作扩展

在LinqPad的Results选项卡上创建一个带有点击操作的按钮非常简单:

using LINQPad.Controls;
void Main()
{
    var btn = (new Button("Click me", (Button b) =>
    {
        // display message on click, then hide button
        "Button was clicked".Dump();
        b.Visible = false;
    })).Dump();
}


但有时候,如果你可以单击一个按钮来对特定的行执行操作,这会很有用--换句话说,产生如下输出的东西:
x1c 0d1x的数据
您可以通过编写一个扩展来实现这一点(您可以将其存储在“我的扩展”中,如前所述-但是您也可以在LinqPad程序中拥有一个单独的静态扩展类)。
扩展类的 backbone :

public static class Extensions
{   
    // add here: ActionButton<TSource>
        
    // add here: DumpAction<T>

    // optional: DumpActionDict<K, V>
}

    • 下面的所有静态方法都需要在这个静态的非嵌套扩展类**中(或者在前面提到的LinqPad的“My Extensions”中)。

剩下的代码直接进入void Main() { ... }方法。注意项目类型必须为C# Program
首先,我们需要有一个行动按钮;为了简单地创建一个,我们使用这个helper方法:

public static LINQPad.Controls.Button ActionButton<TSource>(this TSource arg, 
    string text, System.Action<TSource> selector)
    => new LINQPad.Controls.Button(text, 
       (LINQPad.Controls.Button b) => { selector(arg); });


该函数接受一个源类型,并允许创建一个带有文本和选择器标签的Button(稍后我们将看到它是什么)。
这样,我们就可以定义一个DumpAction方法,如下所示:

public static void DumpAction<T>(this IEnumerable<T> lst, Action<T> selector,
                    string description = "", string clickText = "Click me")
{
    lst.Select(val => new
    {
        val, click = val.ActionButton<T>(clickText, selector)
    }).Dump(description);
}


这将附加一列,其中包含按钮,您可以单击。然后我们需要一个DumpClick方法

public static void DumpClick<T>(this IEnumerable<T> data, string description="", string text = "")

{
    if (!string.IsNullOrEmpty(description)) text.Dump(description);
    foreach (var element in data)
    {
        Util.OnDemand(element.ToString(), () => myFunc(element) ).Dump();
    }
    if (!string.IsNullOrEmpty(description)) "--------".Dump();
}


您可以按如下方式使用它:

// list to display
var myList = new List<string>()
{
    "Apple", "Pie"
};


你要做的就是:

myList.DumpAction((x) => myAction(x), "Click Extension");

它的作用本质上与.Dump()方法相同。现在需要做的就是定义一个被调用的方法myAction

void myAction(string payload)
{
    payload.Dump("myAction");
}


如果单击按钮并将列表项的字符串值传递给它,则将调用此方法。

**注意:**你可以对字典做同样的事情,上面的扩展已经适用于它们,但是它在结果窗口中占用了大量的空间-为了解决这个问题,你可以定义第二个扩展方法:

public static void DumpActionDict<K, V>(this IEnumerable<KeyValuePair<K, V>> lst, 
                    Action<K> selector,
                    string description = "", string clickText = "Click me")
                    
{
    lst.Select(val => new
    {
        val.Key, val.Value, click = val.Key.ActionButton<K>(clickText, selector)
    }).Dump(description);
}


像这样使用它:

var myDict = new Dictionary<string, string>()
{
    ["a"] = "x",
    ["b"] = "y"
};

myDict.DumpActionDict((x) => myAction(x), "Extension for dict");

**注意:**按钮内的文字也可以有不同的格式,看看这个例子:

public static LINQPad.Controls.Button ActionButton<TSource>(this TSource arg, string text,
    System.Action<TSource> selector)
{
    var btn = new LINQPad.Controls.Button(onClick: (LINQPad.Controls.Button b) => { selector(arg); });
    btn.HtmlElement.InnerHtml = $"<small>{text}</small>";
    return btn;
}


这将使按钮文本变小。您可以使用任何HTML元素。

使用Util.HighlightIf为转储着色

您可以使用Util.HighlightIf(condition, object)Util.HighlightIf(condition, htmlcolor, object)创建彩色转储。
下面的例子摘自LinqPad的发行说明,并对其进行了着色,展示了如何:

void Main()
{
    (from file in new DirectoryInfo(Util.LINQPadFolder).GetFiles()
    select 
        Util.HighlightIf(file.Extension == ".txt", "lightblue",
        Util.HighlightIf(file.Extension == ".json" 
                                || file.Extension == ".xml", "lightcyan",
        Util.HighlightIf(file.Extension == ".cmd" 
                                || file.Extension == ".bat", "lightyellow",
        Util.HighlightIf(file.Extension == ".dll", "lightgreen",  
        Util.HighlightIf(file.Extension == ".exe", 
            new {file.Name, 
              Length=Util.HighlightIf(file.Length>999999,"orange",file.Length),
              LastWriteDate=DateTime.Today.Date.ToString("yyyy-MM-dd")}
        )))))).Dump();
}


它有什么作用?它根据细胞的颜色

  • 文件扩展名。文件扩展名.bat.txt.json.cmd.dll.xml.exe每个都有不同的颜色(有些共享相同的颜色)。
  • 文件大小。如果大小超过999999 bytes,则其单元格为橙子。

这将创建一个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";
}

这与前面的转储示例类似,但这次显示了一个漂亮的进度条动画。


JavaScript函数(使用.Dump()

从LinqPad5.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");

如果你已经添加了helper函数

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表达式是如何用于解析变量名的,这不能通过在函数内部使用nameof(paramName)来完成)。

xUnit -使用LinqPad进行单元测试

你知道你可以在LinqPad中编写单元测试吗?例如,您可以使用xUnit框架。对于LinqPad的版本5,它可以通过LinqPad的NUGET支持获得-通过F4 -在对话框中单击Add NUGET.....从LinqPad版本6开始,它是内置的(菜单查询->添加XUnit测试支持)。以下是如何使用use xUnit with LinqPad V5, V6 or V7.的逐步说明

示例1:

[Fact] void TestDb1()
{
    var ctx = this; // "this" represents the database context
    Assert.True(ctx.Categories.Any(), "No categories");
    string.Join(", ", ctx.Categories.Select(s => s.CategoryName).ToList()).Dump("Categories");
    Assert.True(ctx.Products.Any(), "No Products");
    string.Join(", ", ctx.Products.Select(s => s.ProductName).ToList()).Dump("Products");   
}

这个例子需要一个Northwind示例数据库(设置为Linq to SQL或Entity Framework Core Connection),分配给查询,并添加XUnit Test支持(在LinqPad中选择Query -> Add XUnit test support)。它会将所有类别和产品打印到“结果”窗口。如果数据库中没有类别或产品,则测试失败。

示例2:

// for MemberData
public static IEnumerable<object[]> GetNumbers()
{
    yield return new object[] { 5, 1, 3, 9 };  // 1st row: a, b, c, sum (succeeds)
    yield return new object[] { 7, 0, 5, 13 }; // 2nd row: a, b, c, sum (fails)
}

[Theory] 
[MemberData(nameof(GetNumbers))] // easier to handle than [ClassData(typeof(MyClass))]
void Test_Xunit(int a, int b, int c, int expectedSum) 
     => Assert.Equal (expectedSum, a + b + c);

这个例子使用一个[Theory]和成员函数GetNumbers()来填充参数a, b, cexpectedSum,比[Fact]更灵活。[Fact]不能有任何参数。如果预期和不等于a+B+c的和,则测试失败。这是第二行的情况:assert将输出:(a: 7, b: 0, c: 5, expectedSum: 13) .

**注意:**您也可以使用InlineData(例如[InlineData(1,2,3,6)])多次,您甚至可以将其与MemberData属性结合使用。它会将所有值添加到测试中并执行它。

多数据库支持

LinqPad的付费版本(LinqPad 6 Premium)支持在一个查询中使用多个数据库。
下面我将描述如果您选择“Linq to SQL(Optimized for SQL Server)”,您将获得的数据库属性的步骤。

创建新连接或打开现有连接。打开【数据库属性】,选择【一个】数据库(不要使用【全部显示在树视图中】)
x1c4d 1x的
然后勾选“Include Additional Databases”-这将打开另一个对话框,您可以在其中添加多个数据库:



单击“从列表中拾取...”你可以选择+选择另一个数据库。完成后,单击Close关闭其他对话框,然后单击Ok关闭数据库属性。
选择的数据库有“次要”上下文(在“此”UserQuery中列出数据库名称),第一个数据库(在“指定新的或现有的数据库”下选择)是“主要”上下文(这意味着,表直接出现在“此”UserQuery中)。
在“连接”窗口中,这将显示为
“.\MyInstance\AdventureWorks2017 + AdventureWorks2017 + Northwind”
在下面的代码中,我使用“AdventureWorks 2017”作为主上下文,并使用“AdventureWorks 2017”和“Northwind”作为辅助上下文。
像这样准备,你可以做到:

public UserQuery ctx => this; // context
void Main()
{
 // "primary database"
 ctx.Products.Select(s => new {s.ProductID, Name=s.Name}).Take(3).Dump("AdventureWorks");

 // "secondary" databases
 var aw = ctx.AdventureWorks2017;
 var nw = ctx.Northwind;

 nw.Products.Select(s => new {s.ProductID, Name=s.ProductName}).Take(3).Dump("Northwind");
 aw.Products.Select(s => new {s.ProductID, Name=s.Name}).Take(3).Dump("AdventureWorks");
}

本示例中使用的两个示例数据库都来自Microsoft,可以免费下载,它们都有一个Products表,但具有不同的属性/字段:您可以看到我已重命名ProductName / Name,因此它在所有查询中显示为Name。
程序会给予你结果:



下载链接:AdventureWorksNorthwindLinqPad

u59ebvdq

u59ebvdq4#

Dump是一个全局扩展方法,SubmitChanges来自DataContext对象,该对象是System.Data.Linq.DataContext对象。
据我所知,LP只增加了转储和拆卸。虽然我强烈建议在Reflector中打开它,看看还有什么可以使用的。其中一个更有趣的东西是LINQPad.util名称空间,它有一些LINQPad内部使用的好东西。

相关问题