dotnetcore / FreeSql

🦄 .NET aot orm, C# orm, VB.NET orm, Mysql orm, Postgresql orm, SqlServer orm, Oracle orm, Sqlite orm, Firebird orm, 达梦 orm, 人大金仓 orm, 神通 orm, 翰高 orm, 南大通用 orm, 虚谷 orm, 国产 orm, Clickhouse orm, DuckDB orm, TDengine orm, QuestDB orm, MsAccess orm.
https://freesql.net
MIT License
4.12k stars 859 forks source link

Firebird 数据库同步表结构 bug #1913

Open ecocom opened 2 weeks ago

ecocom commented 2 weeks ago

问题描述及重现代码:

Firebird 数据库(5.0),UseAutoSyncStructure(true) 后,发现每次 CRUD 表时同步结构操作始终要执行,且执行失败,调试发现是在反复更新表注释,且用的 SQL 语句是错的:

ALTER TABLE "fx_fxdy" COMMENT  '风险单元'; -- 应该是 COMMENT ON TABLE "fx_fxdy" IS '风险单元';

翻看源码,应该是 FirebirdCodeFirst.GetComparisonDDLStatements() 方法有两处问题,见附图: 第一处标记,应该取 rdb$description 而不是 rdb$external_description 第二处标记,应该用 SQL:COMMENT ON TABLE "xxx" IS 'xxx'

bg

数据库版本

Firebird 5.0

安装的Nuget包

FreeSql.Provider.Firebird 3.2.830

.net framework/. net core? 及具体版本

.net 8.0

2881099 commented 2 weeks ago

这些代码在之前的版本问题,能否跟进了解 5.0 和之前版本的差异,谢谢。

期待反馈!

ecocom commented 2 weeks ago

之前并未在项目中应用过 Firebird,这次是在测试 quickadmin.net 对 Firebird 的支持时发现的此问题,出现问题的实体的定义如下:

[Table(Name = "fx_fxdy")]
[Display(Name = "风险单元")]
public class Fxdy : FullAuditEntityWithUUIDKey, IDeptRelatedEntityWithDeptPath, IEntityWithName, ICRUDEntity<string>
{
    [Column(StringLength = 36)]
    [Display(Name = "风险对象Id")]
    public string FxdxId { get; set; }

    [Column(IsNullable = false, StringLength = 100)]
    [Display(Name = "单元名称")]
    [Required]
    public string Name { get; set; }
    ...
}

FreeSql.Provider.Firebird 在第一次建表时生成的各个注释语句(对各个字段以及表)是 OK 的,看看: https://github.com/dotnetcore/FreeSql/blob/master/Providers/FreeSql.Provider.Firebird/FirebirdCodeFirst.cs#L155 这行用的就是 COMMENT ON TABLE,所以问题就在我上边贴的那两处,第一处(#L271)由于取错了字段,造成每次都要去更新注释,第二处(#L273)则用错了语句,造成异常。

从版本 2.5 到 5.0,Firebird 文档: https://www.firebirdsql.org/file/documentation/html/en/refdocs/fblangref25/firebird-25-language-reference.html#fblangref25-ddl-comment https://www.firebirdsql.org/file/documentation/html/en/refdocs/fblangref30/firebird-30-language-reference.html#fblangref30-ddl-comment https://www.firebirdsql.org/file/documentation/html/en/refdocs/fblangref40/firebird-40-language-reference.html#fblangref40-ddl-comment https://www.firebirdsql.org/file/documentation/html/en/refdocs/fblangref50/firebird-50-language-reference.html#fblangref50-ddl-comment ALTER TABLE 并没有设置注释的功能。另外系统表 RDB$RELATIONS 里存储注释的也都是 RDB$DESCRIPTION 字段而非 RDB$EXTERNAL_DESCRIPTION

之前没人用到过 Firebird 数据库 CodeFirst 给表加注释(备注)?ALTER TABLE "xxx" COMMENT 'xxx' 在哪个 Firebird 版本都没法执行啊

2881099 commented 2 weeks ago

firebird 测试算比较多的,可嵌入式,或并发写入,性能稳定。

可能使用 firebird + codefirst 对比结构的人少吧。

我看了 git history log,可能一开始就写错了,欢迎提 PR,谢谢

2881099 commented 2 weeks ago

fork -> clone -> commit -> PR

欢迎贡献源码

2881099 commented 2 weeks ago

开源项目,非常需要像你这样,愿意深入研究的伙伴。

ecocom commented 2 weeks ago

网络原因上github比较费劲 发现问题我会尽量描述详尽,若能定位到问题所在,会一并指出 开源不易,感谢付出

2881099 commented 2 weeks ago

程序员必备梯子。