使用linq到SQL更新特定列

时间:2016-09-17 14:40:55

标签: c# linq-to-sql

我有一个包含数千个GUID(超过100k)记录的本地列表,我需要更新。

现在我使用简单:

foreach(var id in GUIDs)
{
    var objToUpdate = dataContext.table.Single(o=>o.id==id);

    objToUpdate.val1=...
    objToUpdate.val2=...
    ...


}
dataContext.SubmitChanges();

此解决方案非常慢。每当我调用Single方法时,整个记录都会从DB中检索出来(我不需要它,因为我会覆盖除主键之外的所有数据)。

有什么方法可以只检索我真正需要的两列吗? (主键,另一列)?

当我做这样的事情时:

dataContext.table.Select(o =>

              new sqlRecord
              {
                  PrimaryKey = o.PrimaryKey,
                  AnotherCol = o.AnotherCol
              }
           );

我收到错误:

Explicit construction of entity type '{0}' in query is not allowed.

使用存储过程不是一种选择。根据外部资源设置正确的数据值非常复杂。

var query = dataContext.table.Where(o => GUIDs.Contains(o.id));
foreach(var objToUpdate in query)
{
   objToUpdate.val1 =...;
   objToUpdate.val2 = ...;
}
dataContext.SubmitChanges();

这会产生错误,我使用超过2100个参数,而我有大量的GUID。

为此,我正在使用替代方案:

(from ids in dataContext.fn_getGuidsFromString(String.Join("", GUIDs)) join o in dataContext.table on ids.id equals o.PrimaryKey select o)

其中fn_getGuidsFromString是SQL中的表函数。这比使用where和Contains更好。

我的问题是这个效果太慢了。你必须知道,在这个表中有超过200列,其中一些是ntext,包含大量数据。

dataContext.table.Single(o=>o.id==id);

比这慢约20倍(取决于数据):

dataContext.table.Single(o=>o.id==id).select(o=>new {o.id, o.anotherCol});

但是我无法更新记录。

你有什么建议吗? 此致

1 个答案:

答案 0 :(得分:0)

要从特定列获取值,请使用以下查询:

var objToUpdate = (from o in dataContext.Table
                   where o.id == guid
                   select new {o.Column1, o.Column2, ...}).Single();

select new {...} 语法很重要,因为它投射到不属于上下文跟踪的匿名类型。如果获得的对象是上下文跟踪的一部分,那么接下来使用Attach方法时会收到错误,因为您无法使用相同的主键跟踪两个对象,而Attach将添加一个带有主键。

现在,要更新数据库,只需使用更新的值并使用正确的主键创建实体的存根:

TableName stub = new TableName();
// One of these should be a primary key.
stub.val1 = ...;
stub.val2 = ...;
TableName.Attach(stub); // Will throw an exception if the row with this primary key is already being tracked in memory.

完成所有更改后,请致电

 dataContext.SubmitChanges();

重要的是,如果不需要旧值并且主键都已知,则可以跳过用于引入旧行的查询。可以在不先查询数据库的情况下添加存根,然后在调用SubmitChanges时,将更新正确的行。