以编程方式在LinqPad中执行类似“Hyperlinq”的查询

时间:2014-11-19 01:52:02

标签: c# magento linqpad

我使用LinqPad和MySQL IQ驱动程序来查询来自Magento数据库的数据。我不仅使用它来报告数据库,还进行更新。我可以使用标准的SubmitChanges()方法来更新数据,但这通常会导致无法忍受的缓慢更新,这可能需要花费数小时 - 我的一个表有35,707条记录,我会定期重新创建。

因此我在LinqPad查询中生成SQL语句,然后在选择" SQL"之后在单独的选项卡中执行它们。在语言下拉列表中。

例如,我的输出可能是这样的:

UPDATE catalog_category_product SET position = 6040 WHERE (category_id = 156 AND product_id = 12648);
UPDATE catalog_product_entity_media_gallery_value SET label = 'Sandy Beach' WHERE ((store_id = 0) AND (value_id = 8791));
-- Done.

我最近发现LinqPad有一个很好的类叫Hyperlinq,允许我编写这样的代码:

(new Hyperlinq(QueryLanguage.SQL, myGeneratedSqlText, "Run Query")).Dump();

结果是在输出窗口中放置了一个hyperlinq,它将在一个新选项卡中运行查询(在我的示例中为myGeneratedSqlText的内容)并执行查询。

这很方便。

但是,我现在希望能够保存已执行查询的日志。似乎并不是(一种简单的)内置方式来手动执行"生成的"在LinqPad中查询。我当然可以使用Util.Run来执行现有的已保存查询,实际上我做了类似这样的事情:

Util
    .OnDemand("Run Query", () =>
    {
        var fn = createOutputQueryFileName(); // Timestamped query name
        System.IO.File.WriteAllText(fn, myGeneratedSqlText);
        var run = Util.Run(fn, QueryResultFormat.Text);
        var result = run.AsString();
        return result.StartsWith("[]") ? "Success" : result;
    })
    .Dump();

唯一的戏剧是我必须在myGeneratedSqlText中添加以下文字作为前缀:

var preamble = @"<Query Kind=""SQL"">
  <Connection>
    <ID>ec026b74-8d58-4214-b603-6d3145e03d7e</ID>
    <Driver Assembly=""IQDriver"" PublicKeyToken=""5b59726538a49684"">IQDriver.IQDriver</Driver>
    <Provider>Devart.Data.MySql</Provider>
    <CustomCxString>[DELETED]</CustomCxString>
    <Server>127.0.0.1</Server>
    <Database>prod_1_8</Database>
    <Password>[DELETED]</Password>
    <UserName>[DELETED]</UserName>
    <NoPluralization>true</NoPluralization>
    <NoCapitalization>true</NoCapitalization>
    <DisplayName>Production Tunnel</DisplayName>
    <EncryptCustomCxString>true</EncryptCustomCxString>
    <Persist>true</Persist>
    <DriverData>
      <StripUnderscores>false</StripUnderscores>
      <QuietenAllCaps>false</QuietenAllCaps>
      <Port>6606</Port>
    </DriverData>
  </Connection>
</Query>
";

我真的想避免所有这些序言内容,并在我的Util.OnDemand(...)代码中包含这样的一行:

var run = Util.Run(QueryLanguage.SQL, myGeneratedSqlText, QueryResultFormat.Text);

(但这种方法不存在。)

此处的关键要求是在LinqPad输出窗口中显示hyperlinq,如果单击该窗口,则会将查询作为日志保存到磁盘并执行查询。

有人能建议我干净利落的方式吗?

1 个答案:

答案 0 :(得分:2)

我希望我能正确理解你。当您在顶部栏中选择了连接时,您的UserQuery将成为datacontext。因此,您可以在基于Hyperlinq的操作中的 this 上使用ExecuteQuery和ExecuteCommand。

new Hyperlinq(() => {
                "do log work here".Dump();
                this.ExecuteQuery<string>(generatedSelect).Dump("Results");
                this.ExecuteCommand(generatedCommand).Dump("Results");
             }, "Run Query").Dump();

不幸的是,这会输出到当前标签,但希望这至少会让你完成大部分工作:)

以下是工作中的图像:

Example

当您使用MySQL时,您可以通过上的连接属性进行访问:

new Hyperlinq(() => {
            "do log work here".Dump();
            using (var command = this.Connection.CreateCommand())
            {
                // Usual command logic here
            }
         }, "Run Query").Dump();
相关问题