使用linq to SQL更新特定列
本文关键字:更新 SQL linq to 使用 | 更新日期: 2023-09-27 18:07:26
我有一个需要更新的数千个GUID(超过100k)记录的本地列表。
现在我使用简单的:
foreach(var id in GUIDs)
{
var objToUpdate = dataContext.table.Single(o=>o.id==id);
objToUpdate.val1=...
objToUpdate.val2=...
...
}
dataContext.SubmitChanges();
这个解决方案非常慢。每次当我调用单个方法时,整个记录从DB检索,(我不需要它,因为我覆盖了所有这些数据,除了主键)。
是否有任何方法我可以检索只有两列,我真的需要吗?(主键和另一列)?
当我做这样的事情时:
dataContext.table.Select(o =>
new sqlRecord
{
PrimaryKey = o.PrimaryKey,
AnotherCol = o.AnotherCol
}
);
i get error:
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多个列,其中一些是包含大量数据的文本。
dataContext.table.Single(o=>o.id==id);
大约比下面的慢20倍(取决于数据):
dataContext.table.Single(o=>o.id==id).select(o=>new {o.id, o.anotherCol});
但是我不能更新记录。
你有什么建议吗?关于
要获取特定列的值,请使用以下查询:
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时,将更新正确的行。