FreeSql使用

目的:

1.方库分表
2.主从分离

3.分布式事务

过程:

官网:指南 | FreeSql 官方文档

1.Startup.cs 添加配置(本地数据库MySql)

ConfigureServices:

           Func<IServiceProvider, IFreeSql> fsql = r =>
            {
                IFreeSql fsql = new FreeSql.FreeSqlBuilder()
                    .UseConnectionString(FreeSql.DataType.MySql, @"Data Source=localhost;Database=testfreesql;User ID=root;Password=123456;pooling=true;port=3306;sslmode=none;CharSet=utf8;")
                    .UseMonitorCommand(cmd => Console.WriteLine($"Sql:{cmd.CommandText}"))//监听SQL语句
                    // .UseSlave(@"Data Source = localhost; Database = testfreesql1; User ID = root; Password = 123456; pooling = true; port = 3306; sslmode = none; CharSet = utf8; ", @"Data Source=localhost;Database=testfreesql2;User ID=root;Password=123456;pooling=true;port=3306;sslmode=none;CharSet=utf8;")
                    .UseAutoSyncStructure(true) //自动同步实体结构到数据库,FreeSql不会扫描程序集,只有CRUD时才会生成表。
                    .Build();
                return fsql;
            };
            services.AddSingleton<IFreeSql>(fsql);

Configure:

            //在项目启动时,从容器中获取IFreeSql实例,并执行一些操作:同步表,种子数据,FluentAPI等
            using (IServiceScope serviceScope = app.ApplicationServices.CreateScope())
            {
                var fsql = serviceScope.ServiceProvider.GetRequiredService<IFreeSql>();
                fsql.CodeFirst.SyncStructure(typeof(Blog), typeof(User), typeof(AsTableLog));//Topic 为要同步的实体类
            }

2.引入组件

    <PackageReference Include="FreeSql" Version="3.2.690" />
    <PackageReference Include="FreeSql.Cloud" Version="1.6.3" />
    <PackageReference Include="FreeSql.DbContext" Version="3.2.690" />
    <PackageReference Include="FreeSql.Provider.MySql" Version="3.2.690" />
    <PackageReference Include="FreeSql.Provider.Sqlite" Version="3.2.690" />

 3.创建类(自动生成表)

 4.接口调用

using Db.Entities;
using FreeSql;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace TestFreeSql.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class FreeSqlController : ControllerBase
    {
        //官方文档:https://freesql.net/guide/getting-started.html
        //demo作者微信(qq):842725037


        private readonly ILogger<FreeSqlController> _logger;
        private readonly IFreeSql _freeSql;

        private readonly DbContext  _dbContext;

        private IMemoryCache _cache;
        public FreeSqlController(ILogger<FreeSqlController> logger, IFreeSql freeSql, IMemoryCache cache)
        {
            _logger = logger;
            _freeSql = freeSql;
            _dbContext = freeSql.CreateDbContext();
            _cache = cache;
        }

        /// <summary>
        /// 基础使用(增加、查询、删除、)
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public  async Task<string> TestFreeSqlBase()
        {
            //插入单一数据
            var blog = new Blog() { Rating = 1, Url = DateTime.Now.ToString() };
            var save =await _freeSql.Insert<Blog>(blog).ExecuteAffrowsAsync();
            
            //查询
            var select1 =await _freeSql.Select<Blog>().Where(x => x.BlogId == 1).ToListAsync();
            var select2 = _freeSql.Select<Blog>().ToList();


            //分页查询
            var select4 = _freeSql.Select<Blog>()
               .Where(a => a.BlogId > 1);
            var sql = select4.ToSql();
            var total = await select4.CountAsync();
            var list = await select4.Page(1, 20).ToListAsync();


            //修改
            var select3 =await _freeSql.Select<Blog>().FirstAsync();
            select3.Url = DateTime.Now.ToString();
            var save2 = await _freeSql.InsertOrUpdate<Blog>().SetSource(select3).ExecuteAffrowsAsync();


            //删除
            var delete =await _freeSql.Delete<Blog>().Where(x => x.Url == blog.Url).ExecuteAffrowsAsync();


            return "123";
        }


        /// <summary>
        /// 事务使用
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<string> TestFreeSqlDbContext1()
        {
            //工作单元
            var ctx = _dbContext;

            var blog = new Blog() { Rating = 1, Url = DateTime.Now.ToString() };
            ctx.Set<Blog>().Add(blog);
   
            var user = new User() { Name = DateTime.Now.ToString(), Age=1 };
            ctx.Set<User>().Add(user);

           var save=await ctx.SaveChangesAsync();


            return "123";
        }

        /// <summary>
        /// 事务使用
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<string> TestFreeSqlDbContext2()
        {
            //工作单元
            var ctx = _freeSql.CreateDbContext();

            var blog = new Blog() { Rating = 1, Url = DateTime.Now.ToString() };
            ctx.Set<Blog>().Add(blog);

            var user = new User() { Name = DateTime.Now.ToString(), Age = 1 };
            ctx.Set<User>().Add(user);

            var save = await ctx.SaveChangesAsync();


            return "123";
        }




        /// <summary>
        /// 读从库、写主库,伪功能(需要自己实现数据库数据同步)
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<string> TestFreeSqlReadWrite()
        {
            //文档:https://freesql.net/guide/read-write-splitting.html


            var select2 = _freeSql.Select<Blog>().Where(x=>x.BlogId>0).ToList();//读取从库

            //插入单一数据
            var blog = new Blog() { Rating = 1, Url = DateTime.Now.ToString() };
            var saveSql =await _freeSql.Insert<Blog>(blog).ExecuteAffrowsAsync();//写入主库

            var select3 = _freeSql.Select<Blog>().ToList();//读取从库

            var select4 = _freeSql.Select<Blog>().Master().ToList();//读取主库


            return "123";
        }



        /// <summary>
        /// 分表(自动分表)
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<string> TestFreeSqlSeparate()
        {
            //文档:https://github.com/dotnetcore/FreeSql/discussions/1066

            //插入单一数据
            var asTableLog = new AsTableLog() { msg=DateTime.Now.ToString(), createtime=DateTime.Now};
            var saveSql =await _freeSql.Insert<AsTableLog>(asTableLog).ExecuteAffrowsAsync();

            //插入单一数据
            var asTableLog2 = new AsTableLog() { msg = DateTime.Now.ToString(), createtime = DateTime.Now.AddDays(10) };
            var saveSql2 =await _freeSql.Insert<AsTableLog>(asTableLog2).ExecuteAffrowsAsync();


            //查询
            var select = _freeSql.Select<AsTableLog>();
                    //.Where(a => a.createtime.Between(DateTime.Parse("2022-3-1"), DateTime.Parse("2022-5-1")));
            var sql = select.ToSql();
            var list = select.ToList();

            return "123";
        }




    }
}

5.项目地址:

https://github.com/zhihuixitong/TestFreeSql

总结:

1.使用上感觉一般

2.和EF相比唯一有用的分表使用,分库不支持

3.分布式事务看着复杂没有使用

4.读写分离还好,就是要自己实现数据同步

建议:

1.分库分表完善(分库支持)

2.读写分离完善(自动通过配置自己同步数据)

3.分布式事务使用简单化

4.其他基本功能少花点精力优化,重点优化其他组件没有的功能