2
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

4 回答 4

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 章。

于 2008-12-21T10:50:41.380 回答
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");
}
于 2008-12-21T09:47:29.293 回答
0

我做过类似的事情:

var insInvoice = new NpgsqlCommand(...);
insInvoice.Parameters.With(p => {
    p.Add("_invoice_id", NpgsqlDbType.Uuid, 0, "invoice_id");
    ...
});
于 2008-12-21T09:00:20.543 回答
0

如果您真的有兴趣通过消除其中的噪音和“仪式”来将代码简化为更具可读性的内容,那么在您的示例中还有更大的鱼可炒。

在这种情况下,使用扩展方法、一些静态只读元数据、参数数组等的组合,您应该能够为该插入语句自动生成 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# 元数据。现在要扩展 DB 结构,只需编辑 XML 并重新运行该工具,它就可以让您立即轻松地从代码访问模式。

在不知不觉中,您已经拥有了自己的廉价和愉快的 Linq to SQL 预算版本!

(显然这已经偏离了主题,但为什么不在今年圣诞节用一种简单的方式编写插入语句呢?)

于 2008-12-21T11:05:17.623 回答