我的查询是从app.config中动态检索的。我知道会包含某些列。我想更新处理后返回的每个记录中的列。我可以使用.SubmitChanges()
或类似的方式执行此操作吗?或者我是否必须使用更新sql编写另一个db.ExecuteQuery()
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()
进行跟踪/更新
答案 0 :(得分:1)
为了使用SubmitChanges
更新您的实体,Linq to Sql必须能够跟踪它们。最简单的方法是允许Linq生成您的类型(或者,您也可以使用一堆属性来装饰POCO。)
如果未生成invoice
类型以便Linq to Sql可以跟踪它,则DataContext
将无法确定哪些对象已更改并生成正确的UPDATE
调用SubmitChanges
时的语句。
如果 使用跟踪的实体,并且ObjectTrackingEnabled
设置为true
,但希望使用ExecuteQuery<T>
而不是让Linq to Sql生成您的查询,你仍然需要确保你的SELECT
命令返回所有被跟踪的字段,并且你的表有一个主键(这在documentation of ExecuteQuery<T>
中有解释。)
最后,正如我在原始回答中所解释的那样,您始终可以使用UPDATE
手动执行ExecuteCommand
查询。这就是我执行大部分更新的方式,因为它在大多数情况下更有效,特别是在更新大量实体时,因为Linq to SQL将在服务器上为每个更新执行单独的UPDATE
命令使用SubmitChanges
时的记录,而如果您手动执行,则很可能将其作为单个命令编写。
如果您决定创建自己的UPDATE
语句并使用ExecuteCommand
执行它们,请记住使用参数和不使用连接这样做是为了限制SQL注入攻击。参数化查询的示例可在documentation for ExecuteCommand
中找到。
答案 1 :(得分:0)
总之,这取决于。
在您的情况下,它取决于//对发票做一些事情。 如果您无论如何触摸该部分中每张发票的很多字段,这段代码就可以了。除了您可以在循环外移动提交更改的事实:
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部分。