0

我的查询是从 app.config 动态检索的。我知道某些列将被包括在内。我想更新处理后返回的每条记录中的一列。我可以使用.SubmitChanges()或类似方法吗?还是我必须db.ExecuteQuery()用更新 sql 写另一个?

DataClasses1DataContext db = new DataClasses1DataContext();
IEnumerable<invoice> invoices = db.ExecuteQuery<invoice>(ConfigurationManager.AppSettings["query_sql"].ToString());
foreach (invoice i in invoices)
{
    // do something with the invoice
    // flag the invoice as processed
    i.doc_processed = "Y";
    db.SubmitChanges();
}

更新

感谢 madd0 的回答,我重新设计了我的应用程序允许动态 SQL 的方式。应用程序不是在 app.config 中输入查询,而是查找具有特定名称的 SQL 视图。这样可以添加视图,LINQ 将自动生成类型/类并允许使用跟踪/更新.SubmiteChanges()

4

2 回答 2

1

为了用于SubmitChanges更新您的实体,Linq to Sql 必须能够跟踪它们。最简单的方法是让 Linq 生成你的类型(或者,你也可以用一堆属性装饰 POCO。)

如果invoice没有生成您的类型以便 Linq to Sql 可以跟踪它,则无法DataContext确定哪些对象已更改并在调用UPDATE时生成正确的语句。SubmitChanges

如果您正在使用跟踪实体并ObjectTrackingEnabled设置为true,但想要使用ExecuteQuery<T>而不是让 Linq to Sql 生成查询,您仍然必须确保您的SELECT命令返回所有跟踪字段并且您的表有一个主键(这是在文档中ExecuteQuery<T>解释。)

最后,正如我在原始答案中解释的那样,您始终可以手动执行UPDATE查询ExecuteCommand。这就是我进行大部分更新的方式,因为它在大多数情况下更有效,尤其是在更新大量实体时,因为 Linq to SQL 将UPDATE在使用时在服务器上为每个更新的记录执行单独的命令SubmitChanges,而如果您手动执行,您很可能能够将其编写为单个命令。

如果您决定创建自己的UPDATE语句并使用 执行它们ExecuteCommand,请记住使用参数不是使用连接来这样做,以限制 SQL 注入攻击。参数化查询的示例可ExecuteCommand.

于 2013-03-09T12:11:45.590 回答
0

一如既往,这取决于。

在您的情况下,这取决于 // 对发票进行操作。如果您在该部分中触​​摸每张发票的许多字段,则此代码很好。除了您可以将 submitchanges 移到循环之外:

  foreach (invoice i in invoices)
    {
        // do something with the invoice
        // flag the invoice as processed
        i.doc_processed = "Y";
    }
 db.SubmitChanges();

因此您将受益于单笔交易(尽管仍然是多次更新,因此在性能方面有大量发票不会是最好的)。

如果 // 做某事相对简单明了,我会在查询中编写整个 // 做某事的逻辑并在 sql 中执行,有效地减少你的代码

db.ExecuteQuery<invoice>(ConfigurationManager.AppSettings["do_something_update_query_sql"].ToString());

这种方式将是最高效的,但您不使用 Linq2sql 的任何 ORM 部分。

于 2013-03-09T12:29:33.617 回答