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

Mongodb 支持 #152

Merged
merged 51 commits into from
Jan 21, 2024
Merged

Mongodb 支持 #152

merged 51 commits into from
Jan 21, 2024

Conversation

pengqian089
Copy link
Contributor

暂时还没测试,前端编译了一下午,还在编译

有什么办法嘛?

@pengqian089
Copy link
Contributor Author

单元测试有些通过不了,比如这个

    [Test]
    public async Task SearchTest()
    {
        await ConfigRepository.DeleteAsync(x => true);

        var id = Guid.NewGuid().ToString();
        var source = new Config
        {
            AppId = "001",
            Id = id,
            Group = "group",
            Key = "key",
            Value = "v",
            Description = "d",
            CreateTime = DateTime.Now,
            UpdateTime = DateTime.Now,
            Status = ConfigStatus.Enabled,
            OnlineStatus = OnlineStatus.Online
        };
        var id1 = Guid.NewGuid().ToString();
        var source1 = new Config
        {
            AppId = "001",
            Id = id1,
            Group = "g",
            Key = "k",
            Value = "v",
            Description = "d",
            CreateTime = DateTime.Now,
            UpdateTime = DateTime.Now,
            Status = ConfigStatus.Deleted,
            OnlineStatus = OnlineStatus.Online
        };
        var id2 = Guid.NewGuid().ToString();
        var source2 = new Config
        {
            AppId = "002",
            Id = id2,
            Group = "g",
            Key = "k",
            Value = "v",
            Description = "d",
            CreateTime = DateTime.Now,
            UpdateTime = DateTime.Now,
            Status = ConfigStatus.Deleted,
            OnlineStatus = OnlineStatus.Online
        };
        var result = await service.AddAsync(source, "");
        Assert.IsTrue(result);
        var result1 = await service.AddAsync(source1, "");
        Assert.IsTrue(result1);
        var result2 = await service.AddAsync(source2, "");
        Assert.IsTrue(result2);

        var configs = await service.Search("001", "", "", "");
        Assert.IsNotNull(configs);
        Assert.AreEqual(1, configs.Count);
        var configs1 = await service.Search("", "o", "", "");
        Assert.IsNotNull(configs1);
        Assert.AreEqual(1, configs1.Count);
        var configs2 = await service.Search("", "", "e", "");
        Assert.IsNotNull(configs2);
        Assert.AreEqual(1, configs2.Count);
    }

Search 实现:

    public Task<List<Config>> Search(string appId, string group, string key, string env)
    {
        var q = GetRepository<Config>(env).SearchFor(c => c.Status == ConfigStatus.Enabled && c.Env == env);
        if (!string.IsNullOrEmpty(appId))
        {
            q = q.Where(c => c.AppId == appId);
        }

        if (!string.IsNullOrEmpty(group))
        {
            q = q.Where(c => c.Group.Contains(group));
        }

        if (!string.IsNullOrEmpty(key))
        {
            q = q.Where(c => c.Key.Contains(key));
        }

        return q.ToListAsync();
    }

这是因为 Config 实体没有给 Env 属性赋值,Env 为 null,所以在查询的时候 c.Env == env 条件不成立,
想问一下,这样写单元测试的目的是什么?

@pengqian089
Copy link
Contributor Author

@kklldog
Copy link
Collaborator

kklldog commented Dec 16, 2023

太感谢了,我一直想做这个功能。
不用管单元测试,后面很多单元测试我都没修复。
我最近没空,有空了我会好好看看。

@kklldog
Copy link
Collaborator

kklldog commented Dec 23, 2023

@pengqian089
Hi ,
我今天看了下你的 PR。非常棒。
但是我觉得咱们可能不应该从 IService 层开始隔离 Freesql 跟 Mongodb 。
我抽象了一层 IRepository 作为通用的数据访问接口。
我们的依赖关系是这样:controller > service > repository > (freeSql or mongodb repository)
我会实现 freesql repositories, 你来实现 mongodb repository。
这样的结构的话,后面方便实现其他的驱动,比如 redis。
现在我还没完全重构好,你可以先看看结构。等我实现好了,你再来实现 mongodb 的。
谢谢。

@pengqian089
Copy link
Contributor Author

@kklldog 可以的,我当时就想过了,抽象出Repository,那样只需要维护一个 Service层就好了。
当时写的比较匆忙,所以没有去做

@kklldog
Copy link
Collaborator

kklldog commented Dec 23, 2023

@pengqian089
Hi, 我刚重构了 ConfigService;
并且我把获取 Env 参数放到了 EnvAccessor 里面,然后注入到 EnvFreeSqlFactory里。这样在 Service 里的方法就不用显式写在方法上了。后面这些方法上的 string env 都会拿走。这个你可以注意以下。
重构的东西还很多,估计还需要几个周时间。

@pengqian089
Copy link
Contributor Author

@pengqian089 Hi, 我刚重构了 ConfigService; 并且我把获取 Env 参数放到了 EnvAccessor 里面,然后注入到 EnvFreeSqlFactory里。这样在 Service 里的方法就不用显式写在方法上了。后面这些方法上的 string env 都会拿走。这个你可以注意以下。 重构的东西还很多,估计还需要几个周时间。

@kklldog 好的,如果有需要帮忙的也可以跟我说

@pengqian089
Copy link
Contributor Author

@kklldog 你好,我修改了一部分 注入方式IEventRegister ConfigStatusUpdateRegister ISettingService 的实现重构了一部分,还没有合并到当前PR。

你看看这样的思路可行吗? 如果可行,剩余的部分我也按照这样的方式重构

@kklldog
Copy link
Collaborator

kklldog commented Dec 25, 2023

wow,感谢。
可以啊,原来还可以这样注入瞬态的服务,学到了。
就是有些原来的同步方法,你不用迁就,直接改成异步方法,对应调用的地方也直接改成异步。不用使用 .Result 这种办法来兼容。反正这次重构改动这么多地方,也不差这些了。
我们可以先把代码重构完,然后试跑,把基本功能都做出来。然后补或者干脆全部重写单元测试,拉一下覆盖率。
后面要添加新的驱动就简单了。

@kklldog
Copy link
Collaborator

kklldog commented Dec 25, 2023

新增对 IFreeSqlFactory 实现 DeaultFreesqlFactory,使用默认连接串。因为并不是所有的 repository 都需要根据 env 来切换连接串的。
并且使用 .NET8 中最新的 [FromKeyedServices] 特性来注入正确的实现。

@kklldog
Copy link
Collaborator

kklldog commented Jan 6, 2024

我实现了一个 Unitofwork 模式来包装事务,不知道目前这个抽象能不能适配到 mongodb 上。
mongodb 有事务吗?
@pengqian089

@pengqian089
Copy link
Contributor Author

我实现了一个 Unitofwork 模式来包装事务,不知道目前这个抽象能不能适配到 mongodb 上。 mongodb 有事务吗? @pengqian089

@kklldog mongodb支持有限的事务,只有在集群部署下才可以使用。
可以适配,但是用单服务器部署会报错

@pengqian089
Copy link
Contributor Author

pengqian089 commented Jan 6, 2024

我实现了一个 Unitofwork 模式来包装事务,不知道目前这个抽象能不能适配到 mongodb 上。 mongodb 有事务吗? @pengqian089

@kklldog mongodb支持有限的事务,只有在集群部署下才可以使用。 可以适配,但是用单服务器部署会报错

这里有说明

  • In version 4.0, MongoDB supports multi-document transactions on replica sets.
  • In version 4.2, MongoDB introduces distributed transactions, which adds support for multi-document transactions on sharded clusters and incorporates the existing support for multi-document transactions on replica sets.
  • To use transactions on MongoDB 4.2 deployments (replica sets and sharded clusters), clients must use MongoDB drivers updated for MongoDB 4.2.

mongodb 4.0 以上版本 & 副本集(4.0+)| 分片集(4.2+)

如果是单服务器部署,可以将独立部署转换为单节点副本集启用事务
https://www.mongodb.com/docs/manual/tutorial/convert-standalone-to-replica-set/

好的,我直接实现了一个空的 Uow,你可以去完善它,要么干脆就这样。

Add an empty UoW for mongodb;
@kklldog
Copy link
Collaborator

kklldog commented Jan 6, 2024

目前为止,Freesql 这边基本功能应该差不多了。
Mongodb 我也简单测试了一下,大部分功能应该没啥问题。不过在发布配置的时候会报错。
也就是对应的 ConfigService.Publish 方法,具体大概是 628 行在报错,貌似 configPublishedRepository.UpdateAsync(publishedConfigs) publishedConfigs这个list是个空的(count=0)的时候会报错。
有空可以帮忙查一下,谢谢。
@pengqian089

@kklldog
Copy link
Collaborator

kklldog commented Jan 6, 2024

另外还有一个小问题,syslog表原来为了排序性能主键直接选择了自增。但是看了 mongodb 搞自增应该挺麻烦(估计其他非关系数据库都会麻烦),so 我干脆改成 string 了。但是改成 string 后就不能按 Id desc了。所以我在 SysLogService 里把 Search 方法里的排序指定了 LogTime,但是切到 mongodb 下貌似也在报错,有空的话帮忙看看,谢谢;
· var list = await _sysLogRepository.QueryPageAsync(exp, pageIndex, pageSize, defaultSortField: "LogTime", defaultSortType: "DESC");·

@pengqian089

修复批量更新,空项集合报错的bug;
修复分页排序的问题
@pengqian089
Copy link
Contributor Author

syslog表原来为了排序性能主键直接选择了自增。但是看了 mongodb 搞自增应该挺麻烦(估计其他非关系数据库都会麻烦),so 我干脆改成 string 了。但是改成 string 后就不能按 Id desc了。

这个可以解决 ,如果要改回自增 id ,我也会去适配

@kklldog
Copy link
Collaborator

kklldog commented Jan 7, 2024

syslog表原来为了排序性能主键直接选择了自增。但是看了 mongodb 搞自增应该挺麻烦(估计其他非关系数据库都会麻烦),so 我干脆改成 string 了。但是改成 string 后就不能按 Id desc了。

这个可以解决 ,如果要改回自增 id ,我也会去适配

不用,咱就用string得了,省得对接其他存储的时候麻烦。

@kklldog kklldog added the enhancement New feature or request label Jan 8, 2024
@kklldog kklldog merged commit f932183 into dotnetcore:master Jan 21, 2024
3 checks passed
@kklldog
Copy link
Collaborator

kklldog commented Jan 21, 2024

Thanks very much!
@pengqian089

@pengqian089 pengqian089 deleted the support-mongodb branch July 9, 2024 07:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants