如果with关键字不好(对于C#),这是一个不错的选择吗?

时间:2008-12-21 08:39:23

标签: c# syntactic-sugar

var insInvoice = new NpgsqlCommand(
    @"INSERT INTO invoice_detail(
    invoice_id,
    invoice_detail_id,
    product_id,
    qty,
    price,
    amount)
    VALUES (
    :_invoice_id,
    :_invoice_detail_id,
    :_product_id,
    :_qty,
    :_price,
    :_qty * :_price)", c);


with(var p = insInvoice.Parameters)
{
    p.Add("_invoice_id", NpgsqlDbType.Uuid, 0, "invoice_id");
    p.Add("_invoice_detail_id", NpgsqlDbType.Uuid, 0, "invoice_detail_id");
    p.Add("_product_id", NpgsqlDbType.Uuid, 0, "product_id");
    p.Add("_qty", NpgsqlDbType.Integer, 0, "qty");
    p.Add("_price", NpgsqlDbType.Numeric, 0, "price");
}

kludge:

for(var p = insInvoice.Parameters; false;)
{       
    p.Add("_invoice_id", NpgsqlDbType.Uuid, 0, "invoice_id");
    p.Add("_invoice_detail_id", NpgsqlDbType.Uuid, 0, "invoice_detail_id");
    p.Add("_product_id", NpgsqlDbType.Uuid, 0, "product_id");
    p.Add("_qty", NpgsqlDbType.Integer, 0, "qty");
    p.Add("_price", NpgsqlDbType.Numeric, 0, "price");      
}

4 个答案:

答案 0 :(得分:6)

当您使用正确的表单获得“添加”方法时,您可以为参数使用集合初始化程序:

var insInvoice = new NpgsqlCommand(sql)
{
    Parameters = 
    {
        { "_invoice_id", NpgsqlDbType.Uuid, 0, "invoice_id" },
        { "_invoice_detail_id", NpgsqlDbType.Uuid, 0, "invoice_detail_id" },
        { "_qty", NpgsqlDbType.Integer, 0, "qty" },
        { "_price", NpgsqlDbType.Numeric, 0, "price" }
    }
};

有关对象和集合初始值设定项的更多信息,您可以免费下载C# in Depth的第8章。

答案 1 :(得分:3)

对于“p”变量的范围,有什么意义?

在这种情况下,只需创建一个带花括号的范围并一起删除with语句,将变量声明“p”移动到新范围中。这样,“p”变量仅在花括号的范围内可用。今天你可以做,而不需要任何语法糖。我不确定这有助于提高可读性,只需将所有大括号一起移除并仅使用变量。

//with(var p = insInvoice.Parameters)
{
  var p = insInvoice.Parameters;
  p.Add("_invoice_id", NpgsqlDbType.Uuid, 0, "invoice_id");
  p.Add("_invoice_detail_id", NpgsqlDbType.Uuid, 0, "invoice_detail_id");
  p.Add("_product_id", NpgsqlDbType.Uuid, 0, "product_id");
  p.Add("_qty", NpgsqlDbType.Integer, 0, "qty");
  p.Add("_price", NpgsqlDbType.Numeric, 0, "price");
}

答案 2 :(得分:0)

我做了类似的事情:

var insInvoice = new NpgsqlCommand(...);
insInvoice.Parameters.With(p => {
    p.Add("_invoice_id", NpgsqlDbType.Uuid, 0, "invoice_id");
    ...
});

答案 3 :(得分:0)

如果您真的有兴趣通过消除噪音和“仪式”来将代码降低到更具可读性,那么在您的示例中可以使用更大的鱼来煎炸。

在这种情况下,使用扩展方法,一些静态只读元数据,params数组等的组合,您应该能够为该插入语句自动生成SQL,而不必手动编写它。为什么任何给定的插入看起来都比这更复杂:

db.Insert(Invoices.Table,
      new Value(Invoices.ID, "{something-something}"),
      new Value(Invoices.Quantity, 52),
      /*... and so on*/);

无需手动编写大型SQL插件。根据列名自动选择参数名称。名称类型和大小信息都绑定在Invoices的那些静态成员中,因此您不会错误。在呼叫点处彼此相邻指定的名称和值。这一切都可能是你的!

可选地,以一些整洁的XML结构声明数据库的结构,并编写一个工具,从该XML生成两件事:1。用于设置数据库的DDL和2.用于每个表及其列的C#元数据。现在,为了扩展数据库结构,只需编辑XML并重新运行该工具,它就可以让您从代码中轻松访问模式。

在您知道之前,您已经拥有了自己的廉价且开朗的Linq to SQL预算版本!

(显然这偏离了主题,但为什么不在今年圣诞节那样轻松地编写插入语句呢?)