dotnetcore / dotnetcore/FreeSql
使用 IBaseRepository.Update 批量更新由 IncludeMany 加载的子项时出现异常
- Dominant language
- C#
- Stars
- 4.4k
- Forks
- 910
- PR merge metrics
- No merged PRs in 30d
Description
#### 问题描述及重现代码:
使用 IBaseRepository.Update 批量更新由 IncludeMany 加载的子项时出现异常
```c#
using FreeSql;
using FreeSql.DataAnnotations;
var freeSql = new FreeSqlBuilder()
.UseConnectionString(DataType.Sqlite, "Data Source=:memory:")
.UseMonitorCommand(cmd => Console.WriteLine(cmd.CommandText))
.Build();
await freeSql.Ado.ExecuteNonQueryAsync(
"""
CREATE TABLE Foo (
Id INTEGER PRIMARY KEY AUTOINCREMENT,
Name TEXT NOT NULL
);
CREATE TABLE Bar (
Id INTEGER PRIMARY KEY AUTOINCREMENT,
FooId INTEGER NOT NULL,
Value TEXT,
FOREIGN KEY (FooId) REFERENCES Foo(Id)
ON DELETE CASCADE
ON UPDATE CASCADE
);
INSERT INTO Foo (Name) VALUES ('Foo A');
INSERT INTO Foo (Name) VALUES ('Foo B');
INSERT INTO Bar (FooId, Value) VALUES (1, 'Bar 1');
INSERT INTO Bar (FooId, Value) VALUES (1, 'Bar 2');
INSERT INTO Bar (FooId, Value) VALUES (2, 'Bar 3');
"""
);
var fooRepo = freeSql.GetRepository();
var barRepo = freeSql.GetRepository();
// IncludeMany 一对多并批量更新子项导致 System.Exception: FreeSql: Not updatable,
// data not tracked, should be queried first or Attach 异常
var foos = await fooRepo.Select.IncludeMany(f => f.Bars).ToListAsync();
var bars = foos[0].Bars;
bars.ForEach(b => b.FooId = 2);
await barRepo.UpdateAsync(bars); // <-- Exception here!
// 循环逐一更新子项无问题
// var foos = await fooRepo.Select.IncludeMany(f => f.Bars).ToListAsync();
// var bars = foos[0].Bars;
// bars.ForEach(b => b.FooId = 2);
// foreach (var bar in bars)
// await barRepo.UpdateAsync(bar);
// 手动加载子项再批量更新也无问题
// var foos = await fooRepo.Select.ToListAsync();
// foreach (var foo in foos)
// foo.Bars = await barRepo.Where(b => b.FooId == foo.Id).ToListAsync();
//
// var bars = foos[0].Bars;
// bars.ForEach(b => b.FooId = 2);
// await barRepo.UpdateAsync(bars);
public class Foo
{
[Column(IsPrimary = true, IsIdentity = true)]
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
[Navigate(nameof(Bar.FooId))]
public List Bars { get; set; } = [];
}
public class Bar
{
[Column(IsPrimary = true, IsIdentity = true)]
public int Id { get; set; }
[Navigate(nameof(FooId))]
public Foo? Foo { get; set; }
public int FooId { get; set; }
public string Value { get; set; } = string.Empty;
}
```
异常信息
```
Unhandled exception. System.Exception: FreeSql: Not updatable, data not tracked, should be queried first or Attach:(1, 2, Bar 1)
at FreeSql.DbSet`1.CanUpdate(TEntity data, Boolean isThrow)
at FreeSql.DbSet`1.CanUpdate(IEnumerable`1 data, Boolean isThrow)
at FreeSql.DbSet`1.UpdateRangePriv(IEnumerable`1 data, Boolean isCheck)
at FreeSql.DbSet`1.UpdateRange(IEnumerable`1 data)
at FreeSql.BaseRepository`1.UpdateAsync(IEnumerable`1 entitys, CancellationToken cancellationToken)
at Program.$(String[] args) in D:\Repositories\FreeSqlIssues\Program.cs:line 44
at Program.(String[] args)
```
查看异常提示需要先 Attach, 在 Update 前调用 barRepo.Attach(bars) 能解决这个问题
#### 数据库版本
```
```
#### 安装的Nuget包
```
```
#### .net framework/. net core? 及具体版本
```
net10.0
```
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.