-
Notifications
You must be signed in to change notification settings - Fork 898
Open
Description
问题描述及重现代码:
使用 IBaseRepository.Update 批量更新由 IncludeMany 加载的子项时出现异常
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<Foo>();
var barRepo = freeSql.GetRepository<Bar>();
// 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<Bar> 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.<Main>$(String[] args) in D:\Repositories\FreeSqlIssues\Program.cs:line 44
at Program.<Main>(String[] args)
查看异常提示需要先 Attach, 在 Update 前调用 barRepo.Attach(bars) 能解决这个问题
数据库版本
<PackageReference Include="Microsoft.Data.Sqlite" Version="10.0.2" />
安装的Nuget包
<PackageReference Include="FreeSql.Provider.SqliteCore" Version="3.5.305" />
<PackageReference Include="FreeSql.Repository" Version="3.5.305" />
.net framework/. net core? 及具体版本
<TargetFramework>net10.0</TargetFramework>
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels