Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IsRowversion设置数据库伪列报错问题! #825

Closed
worldofchu opened this issue Jul 19, 2021 · 15 comments
Closed

IsRowversion设置数据库伪列报错问题! #825

worldofchu opened this issue Jul 19, 2021 · 15 comments

Comments

@worldofchu
Copy link

问题描述及重现步骤:

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
@worldofchu
Copy link
Author

请问作者 何时能更正#825 啊 ,想尽早使用!谢谢!

@worldofchu
Copy link
Author

请问作者 何时能更正#825 啊 ,想尽早使用!谢谢!!!!+1

@2881099
Copy link
Collaborator

2881099 commented Aug 28, 2021

考虑每个数据库标准不同,伪劣暂时不支持。

@2881099
Copy link
Collaborator

2881099 commented Aug 28, 2021

现在支持 int/long 以及 byte[]

@worldofchu
Copy link
Author

可否放开个口子呢,类似 比如注解或者flunetapi 加个布尔参数,来使得 指定字段 insert 和update时不set值,但是指定字段 在select时刻和where 如现在一样的rowversion表现即可????

@sdwdjzhy
Copy link

sdwdjzhy commented Oct 28, 2021

环境: sql server 2008r2

[FreeSql.DataAnnotations.Column(CanUpdate = false, CanInsert = false)] 就可以不更新此列了

@worldofchu
Copy link
Author

我今天验证了下, _tbrepo.Orm.Update().SetSource(tb111).ExecuteAffrows();
使用了freesql 2.6.1版本和 postgresql12+ 字段都设置了canupdate caninsert false 但是上述语句不生效!!!还是不行的!

@worldofchu
Copy link
Author

当然 我同时设置了 .IsVersion(true)

@sdwdjzhy
Copy link

sdwdjzhy commented Nov 4, 2021

没用过 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,会不会成功

@worldofchu
Copy link
Author

worldofchu commented Nov 4, 2021

sqlserver 的Timestamp 字段多么完美!!你为啥非得不用呢?目的不就是为了 使用它么(使用它作为rowversion)

@sdwdjzhy
Copy link

sdwdjzhy commented Nov 4, 2021

没办法啊,他又不支持 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,加了就报错

@worldofchu
Copy link
Author

手动加 我何必使用 不够麻烦的。其实源代码也能改,但是我们无法长期保持跟进。

@worldofchu
Copy link
Author

worldofchu commented Nov 4, 2021

其实源码 FreeSql-2.6.100\FreeSql\Internal\CommonProvider.cs文件 第790行代码
if (_table.VersionColumn != null) 修正为 if (_table.VersionColumn != null&& _table.VersionColumn.Attribute.CanUpdate) 理论上就行了。。不过我没test

@worldofchu
Copy link
Author

考虑每个数据库标准不同,伪劣暂时不支持。

--恳请作者再次考虑下,其实只是在 Updatesql 在遇到VersionColumn 字段时刻考虑一下该字段是否canupdate即可
本身这个字段默认为true,也不影响默认效果。
但是 ,其他有需要的开发者就可以 在model配置时刻设置 某字段为rowversion和canupdate=false 从而满足这种需求且不影响 原本的默认行为!!!
@2881099

@2881099
Copy link
Collaborator

2881099 commented Oct 2, 2022

其实不用太纠结,freesql考虑更多数据库通用,TableInfo VersionColumn 可以通过反射修改的。

@2881099 2881099 closed this as completed Oct 2, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants