使用 LINQ to SQL 进行批量更新

发布于 2024-12-01 16:05:16 字数 227 浏览 0 评论 0原文

有没有办法使用 LINQ 对集合进行批量更新?目前,如果我有一个 List 并且我想将列表中每一行的 column1 更新为等于 TEST,我将设置一个 foreach 循环,然后为每个单独的对象设置值,然后保存它。这工作正常,但我只是想知道是否有一些 LINQ 方法在那里我可以做类似 myOject.BulkUpdate(columnName, value) 的事情?

Is there a way to do a bulk update on a collection with LINQ? Currently if I have a List<myObject> and I want to update column1 to equal TEST for every row in the List I would setup a foreach loop and then for each individual object I would set the value and then save it. This works fine but I was just wondering if there was some LINQ method out there where I could do something like myOject.BulkUpdate(columnName, value)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

沩ん囻菔务 2024-12-08 16:05:16

使用 Linq 表达式和 Terry Aney 关于此主题的优秀库,您的要求完全可以实现。

使用 LINQ to SQL 进行批量更新和删除

您给出的示例的更新如下:

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

Your requirement here is entirely possible using Linq expressions and Terry Aney's excellent library on this topic.

Batch Updates and Deletes with LINQ to SQL

An update in the terms of the example you gave would be as follows:

using BTR.Core.Linq;
...

Context.myObjects.UpdateBatch
(
    Context.myObjects.Where(x => x.columnName != value),
    x => new myObject { columnName = value}
);

Edit (2017-01-20): It's worth nothing this is now available in the form of a NuGet package @ https://www.nuget.org/packages/LinqPost/.

Install-Package LinqPost
玩心态 2024-12-08 16:05:16

听起来您正在使用 LINQ To SQL,并且您已经掌握了基础知识。

LINQ To SQL 是将表抽象为类,并没有真正提供您正在寻找的“灵丹妙药”或一句简短的话。

做到这一点的唯一方法是实现您的单行代码,即创建一个存储过程来获取该列名称和新值,并自己实现该逻辑。

 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();

Sounds like you're using LINQ To SQL, and you've got the basics laid out already.

LINQ To SQL is about abstracting tables into classes, and doesn't really provide the 'silver bullet' or one-liner you are looking for.

The only way to do that is to achieve your one-liner would be to make a stored proc to take that column name and new value, and implement that logic yourself.

 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. */

Otherwise, it's as you describe:

 List<Customer> myCusts = db.Customers.ToList();
 foreach(Customer c in myCusts)
 {
     c.Name = "TEST";
 }     
 db.SubmitChanges();
一身仙ぐ女味 2024-12-08 16:05:16

LINQ to SQL(或 EF)就是将对象放入内存,操作它们,然后使用每行的单独数据库请求来更新它们。

如果不需要在客户端上水合整个对象,最好使用服务器端操作(存储过程、TSQL)而不是 LINQ。您可以使用 LINQ 提供程序针对数据库发出 TSQL。例如,使用 LINQ to SQL,您可以使用 context.ExecuteCommand("Update table set field=value where condition"),只需注意 SQL 注入

LINQ to SQL (or EF for that matter), is all about bringing objects into memory, manipulating them, and then updating them with separate database requests for each row.

In cases where you don't need to hydrate the entire object on the client, it is much better to use server side operations (stored procs, TSQL) instead of LINQ. You can use the LINQ providers to issue TSQL against the database. For example, with LINQ to SQL you can use context.ExecuteCommand("Update table set field=value where condition"), just watch out for SQL Injection.

美男兮 2024-12-08 16:05:16

EF Core 7.0 引入了批量更新和批量删除。

例如,考虑以下 LINQ 查询,该查询通过调用 ExecuteUpdateAsync 终止:

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 来立即更新给定年份之前发布的帖子的所有标签的“文本”列:

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)

EF Core 7.0 introduces Bulk Update and Bulk Delete.

For example, consider the following LINQ query terminated with a call to ExecuteUpdateAsync:

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)"));

This generates SQL to immediately update the “Text” column of all tags for posts published before the given year:

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)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文