IsRowversion设置数据库伪列报错问题!
问题描述及重现步骤:
pg数据库,设置xmin伪列作为乐观锁字段,然后update报错,发现set xmin=。。。 实体特性本身也设置了canupdate为false。 建议!IsRowversion 增加开关量设置 可以使rowversion字段不参与update的set。 因为 例如sqlserver pg 都有对应的伪列进行乐观锁,oracle也有不太严谨的orarowscn,sqlserver更是专门的timestamp类型。
请求作者 进行 IsRowversion 增加开关量设置 可以使rowversion字段不参与update的set。 谢谢!
数据库的具体版本
pg12+
安装的包
.net framework/. net core? 及具体版本
net6
请问作者 何时能更正#825 啊 ,想尽早使用!谢谢!
请问作者 何时能更正#825 啊 ,想尽早使用!谢谢!!!!+1
考虑每个数据库标准不同,伪劣暂时不支持。
现在支持 int/long 以及 byte[]
可否放开个口子呢,类似 比如注解或者flunetapi 加个布尔参数,来使得 指定字段 insert 和update时不set值,但是指定字段 在select时刻和where 如现在一样的rowversion表现即可????
环境: sql server 2008r2
[FreeSql.DataAnnotations.Column(CanUpdate = false, CanInsert = false)] 就可以不更新此列了
我今天验证了下, _tbrepo.Orm.Update<Tb>().SetSource(tb111).ExecuteAffrows(); 使用了freesql 2.6.1版本和 postgresql12+ 字段都设置了canupdate caninsert false 但是上述语句不生效!!!还是不行的!
当然 我同时设置了 .IsVersion(true)
没用过 pg,我用的是 sql server
/// <summary>
/// tAd
/// </summary>
[DbTable]
[DisplayName("tTest")]
public partial class tTest
{
/// <summary>
/// 编号
/// </summary>
[Display(Name = "编号")]
[Key]
[System.ComponentModel.DataAnnotations.Schema.DatabaseGenerated(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.None)]
#if NET5_0_OR_GREATER
[FreeSql.DataAnnotations.Column(CanInsert = true, CanUpdate = true)]
#endif
public int Id { get; set; }
/// <summary>
/// 名称
/// </summary>
[Display(Name = "名称")]
[StringLength(255, MinimumLength = 0)]
[Required(ErrorMessage = "名称 - 不能为空")]
public string Name { get; set; }
/// <summary>
/// RowVersion
/// </summary>
[Display(Name = "RowVersion")]
[Timestamp]
#if NETCOREAPP3_1 || NET5_0
[FreeSql.DataAnnotations.Column(CanUpdate = false, CanInsert = false)]
#endif
public byte[] RowVersion { get; set; }
使用
public async Task<IActionResult> Test()
{
var test = await freesql.Select<tTest>().FirstAsync();
await freesql.Update<tTest>(test).Set(i => i.Name, "bbb").ExecuteAffrowsAsync();
return Ok("dddd");
}
刚刚测试过,没有问题,可以更新的。
但是如果加上 了 IsVersion = true, 就抛出异常了
System.Exception: 不能更新时间戳列。
---> Microsoft.Data.SqlClient.SqlException (0x80131904): 不能更新时间戳列。
所以,你试试不加 IsVersion = true,会不会成功
sqlserver 的Timestamp 字段多么完美!!你为啥非得不用呢?目的不就是为了 使用它么(使用它作为rowversion)
没办法啊,他又不支持 Timestamp 自动绑定where
await freesql.Update<tTest>(test).Where(i => i.Id == test.Id && i.RowVersion == test.RowVersion).Set(i => i.Name, "ccc").ExecuteAffrowsAsync();
那就手动加上 RowVersion 的where呗。 反正不能加 IsVersion = true,加了就报错
手动加 我何必使用 不够麻烦的。其实源代码也能改,但是我们无法长期保持跟进。
其实源码 FreeSql-2.6.100\FreeSql\Internal\CommonProvider.cs文件 第790行代码 if (_table.VersionColumn != null) 修正为 if (_table.VersionColumn != null&& _table.VersionColumn.Attribute.CanUpdate) 理论上就行了。。不过我没test
考虑每个数据库标准不同,伪劣暂时不支持。
--恳请作者再次考虑下,其实只是在 Updatesql 在遇到VersionColumn 字段时刻考虑一下该字段是否canupdate即可 本身这个字段默认为true,也不影响默认效果。 但是 ,其他有需要的开发者就可以 在model配置时刻设置 某字段为rowversion和canupdate=false 从而满足这种需求且不影响 原本的默认行为!!! @2881099
其实不用太纠结,freesql考虑更多数据库通用,TableInfo VersionColumn 可以通过反射修改的。