有没有办法使用LINQ批量更新集合?如果我有一个List<myObject>
,并且我想将列表中每一行的column1更新为TEST,那么我会设置一个foreach循环,然后对于每个单独的对象,我会设置值,然后保存它。这样做是可以的,但我想知道是否有一些LINQ方法可以像myOject.BulkUpdate(columnName, value)
这样实现?
有没有办法使用LINQ批量更新集合?如果我有一个List<myObject>
,并且我想将列表中每一行的column1更新为TEST,那么我会设置一个foreach循环,然后对于每个单独的对象,我会设置值,然后保存它。这样做是可以的,但我想知道是否有一些LINQ方法可以像myOject.BulkUpdate(columnName, value)
这样实现?
你的要求可以通过使用Linq表达式和Terry Aney关于此主题的出色库完全实现。
根据你给出的示例,更新操作如下:
using BTR.Core.Linq;
...
Context.myObjects.UpdateBatch
(
Context.myObjects.Where(x => x.columnName != value),
x => new myObject { columnName = value}
);
编辑(2017-01-20):值得一提的是,现在可以通过NuGet包@https://www.nuget.org/packages/LinqPost/获得此内容。
Install-Package LinqPost
听起来你正在使用LINQ To SQL,并且已经完成了基本设置。
LINQ To SQL是将表格抽象成类的技术,它不能提供你想要的 'silver bullet' 或者一行代码。
要实现你想要的一行代码,唯一的方法是创建一个存储过程来获取该列名称和新值,并自己实现该逻辑。
db.MassUpdateTableColumn("Customer", "Name", "TEST");
....
CREATE PROC MassUpdateTableColumn
@TableName varchar(100), @ColumnName varchar(100), @NewVal varchar(100)
AS
/*your dynamic SQL to update a table column with a new val. */
List<Customer> myCusts = db.Customers.ToList();
foreach(Customer c in myCusts)
{
c.Name = "TEST";
}
db.SubmitChanges();
LINQ to SQL(或者说EF),它的主要作用是将对象带入内存,对其进行操作,然后使用单独的数据库请求更新每一行。
在不需要在客户端上完全填充对象的情况下,最好使用服务器端操作(存储过程、TSQL)而不是LINQ。您可以使用LINQ提供程序针对数据库发出TSQL。例如,使用LINQ to SQL,您可以使用context.ExecuteCommand("Update table set field=value where condition"),只需注意SQL注入。
EF Core 7.0 引入了批量更新和批量删除功能。
例如,考虑以下以调用 ExecuteUpdateAsync
结尾的 LINQ 查询:
var priorToDateTime = new DateTime(priorToYear, 1, 1);
await context.Tags
.Where(t => t.Posts.All(e => e.PublishedOn < priorToDateTime))
.ExecuteUpdateAsync(s => s.SetProperty(t => t.Text, t => t.Text + " (old)"));
这将生成SQL语句,立即更新给定年份之前发布的所有帖子的标签“Text”列:
UPDATE [t]
SET [t].[Text] = [t].[Text] + N' (old)'
FROM [Tags] AS [t]
WHERE NOT EXISTS (
SELECT 1
FROM [PostTag] AS [p]
INNER JOIN [Posts] AS [p0] ON [p].[PostsId] = [p0].[Id]
WHERE [t].[Id] = [p].[TagsId] AND [p0].[PublishedOn] < @__priorToDateTime_1)