我可以更新使用db.ExecuteQuery()检索的LINQ-to-SQL记录吗?

时间:2013-03-09 11:30:51

标签: c# .net linq linq-to-sql

我的查询是从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()进行跟踪/更新

2 个答案:

答案 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部分。