第 1 部分,共 2 部分
除了众所周知的myQuery.Dump("Query result:"),另一个值得一提的特性是Util 类:它包含许多非常方便的方法(其中一些我已经提到,但还有很多)。
另外有趣的是,您可以修改Dump() 的工作方式。
最后,我将向您展示如何使用SubmitChanges() 或SaveChanges() 以及永久更改(即插入、更新、删除LINQ 查询)以及如何访问 LinqPad 的内部连接对象。
为了总结,我将向您展示如何在 LinqPad 中创建简单的 2d 图形(绘制线条、位图或函数)。
所以,这里有一组内置 LinqPad 功能(根据我自己使用该工具的经验):
.Dump()
(LinqPad v5.03.08 及更高版本中可用的参数)
.Dump() 扩展方法消耗并打印(几乎)所有内容。
但是您知道有几个参数可用吗?
看看这段代码sn-p:
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 [string] - 如果您提供以逗号分隔的变量列表,它们将从输出中排除(在示例中“a,c”:b 和 d 显示,a 和 @ 987654370@ 已隐藏)
-
exclude [string] 带有“+”前缀 - 前缀反转了 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(); 始终默认显示 ID,但仅在您感兴趣时才显示 customerObject 的详细信息。
更多关于 Dump 的高级主题可以在 here 和 there 找到。
环境
这不是一个 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 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();
此示例从与查询同名且包含在同一路径中的 XML 文件中返回具有属性 attr1 的所有元素,该属性包含值 "a"。查看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 中,您可以使用此帮助函数(nb:获取使用的扩展方法.ToSecureString(),请关注this link at Stackoverflow - 它还允许您将其转换回来如果需要):
System.Security.SecureString GetPasswordSecure(string Name, bool noDefaultSave=true)
{
return Util.GetPassword(Name, noDefaultSave).ToSecureString();
}
Util.Cmd
此方法的工作原理类似于命令处理器。您可以从 Windows 控制台调用您知道的所有命令。
示例 1 - 目录:
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);
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()。
但还有更多!您可以使用以下 sn-p 创建一个简单的 JSON 解析器 - 非常有用,例如,如果您想即时解析和测试 JSON 字符串。 使用文本编辑器将以下 sn-p 保存为 JSONAnalyzer.linq,然后在 LinqPad 中打开它(这是为了方便地即时添加引用):
<Query Kind="Program">
<Reference><RuntimeDirectory>\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 非常有用。
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:
如果你需要显示一个消息框,看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
}
}
(不要忘记按 F4 并添加 Microsoft.VisualBasic.dll 及其命名空间以使其工作)
Util.Run
(新:自LinqPad version v4.52.1 (beta)起可用)
允许您从您的脚本或您自己的 .NET 程序或 Windows 服务中运行另一个 LINQPad 脚本(通过引用LINQPad.exe 的 LINQPad4-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,您可能希望永久更改(对于 insert/update/delete 操作)。
由于数据库上下文是由 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,您可能还希望永久更改(对于 insert/update/delete 操作)。
由于数据库上下文是由 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;
在调用它们之前。
this - 数据库上下文
在 LinqPad 中,通过使用顶部的组合框并为您的查询选择正确的数据库,自动应用 数据库上下文。
但有时,明确引用它很有用,例如,如果您从 Visual Studio 中复制项目中的一些代码,然后将其粘贴到 LinqPad 中。
您从 Visual Studio 项目中获取的代码 sn-p 很可能如下所示:
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.,但这要容易得多。
只需将它添加到您的 sn-p 顶部,如下所示:
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.Connection
将 LinqPad 与 OleDb 结合使用,将数据表转换为 Linq 对象,Linq 中的 SQL 查询
以下代码 sn-p 帮助您将 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();
现在添加到 LinqPad 的 SqlServer 连接并添加 Northwind 数据库以运行此示例。
注意:如果只是想获取当前选中连接的数据库和服务器,可以使用这段代码sn -p:
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.dll、System.Windows.Forms.dll、WindowsFormsIntegration.dll、PresentationCore.dll 和 PresentationFramework.dll 添加到您的 LinqPad 程序中,并添加命名空间 @987654473 @。
第一个例子简单地画了一条线:
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(),它会附加图像。
在 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.dll、System.Windows.Forms.dll、System.Windows.Forms.DataVisualization.dll
并从这些程序集中添加所有命名空间。
其他提示/进一步阅读:
-
想在 Visual Studio 中使用 LinqPad?这是how you can do that。
-
需要将 LinqPad 作为“便携式应用程序”? Read here 怎么做。
-
Joe 的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 左侧的 My Queries 选项卡中编写和存储扩展方法:树的最后一项名为 My Extensions;双击它打开一个文件,您可以在其中编写可用于所有查询的扩展名。将它们放入公共静态类MyExtensions,并使用Main() 方法包含扩展测试。
Continued here...