欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

借助表达式树感受不一样的CRUD

程序员文章站 2022-11-10 21:54:02
借助表达式树感受不一样的CRUD Intro 最近有个想法,想不写 sql 语句,做一个类似于 ORM 的东西,自己解析表达式树,生成要执行的 sql 语句,最后再执行 sql 语句,返回相应结果。 思路解析 常用的 sql 语句基本都有一定的模式,就是 /`DELETE Update SELECT ......

借助表达式树感受不一样的crud

intro

最近有个想法,想不写 sql 语句,做一个类似于 orm 的东西,自己解析表达式树,生成要执行的 sql 语句,最后再执行 sql 语句,返回相应结果。

思路解析

常用的 sql 语句基本都有一定的模式,就是 insert/delete/update/select,我把公用的部分给抽离出来,把查询/更新/删除条件和指定字段通过表达式树来指出,解析传入的表达式树对象来获取条件以及要更新的字段。

源码

源码链接

sample

请看使用示例

安装 nuget 包 wihanli.common

public static class repositorytest
    {
        public static void maintest()
        {
            var connectionpool = new dbconnectionpool(new dbconnectionpoolpolicy(configurationhelper.connectionstring("testdb")));

            var repo = new repository<testentity>(() => connectionpool.get());
            repo.insert(new testentity
            {
                token = "1233",
                createdtime = datetime.utcnow
            });

            var entity = repo.fetch(t => t.pkid == 1);
            system.console.writeline(entity.token);

            repo.update(t => t.pkid == 1, t => t.token, 1);

            entity = repo.fetch(t => t.pkid == 1);
            system.console.writeline(entity.token);

            repo.delete(t => t.pkid == 1);
            entity = repo.fetch(t => t.pkid == 1);
            system.console.writeline($"delete operation {(entity == null ? "success" : "failed")}");

            repo.execute("truncate table dbo.tabtestentity");

            console.writeline("finished.");
        }

        public class dbconnectionpool : defaultobjectpool<dbconnection>
        {
            public dbconnectionpool(ipooledobjectpolicy<dbconnection> policy) : base(policy)
            {
            }

            public dbconnectionpool(ipooledobjectpolicy<dbconnection> policy, int maximumretained) : base(policy, maximumretained)
            {
            }
        }

        public class dbconnectionpoolpolicy : ipooledobjectpolicy<dbconnection>
        {
            private readonly string _connstring;

            public dbconnectionpoolpolicy(string connstring)
            {
                _connstring = connstring;
            }

            public dbconnection create()
            {
                return new sqlconnection(_connstring);
            }

            public bool return(dbconnection obj)
            {
                return obj.connectionstring.isnotnullorwhitespace();
            }
        }
        [table("tabtestentity")]
        internal class testentity
        {
            [databasegenerated(databasegeneratedoption.identity)]
            public int pkid { get; set; }

            public string token { get; set; }

            public datetime createdtime { get; set; }
        }
    }

示例使用了 objectpool 实现了一个数据库连接池,repository 实例化需要一个获取 dbconnection 对象的委托,而数据库连接就是从这数据库连接池中获取。

不足/todo

  • 支持通过 column 自定义列名称
  • 支持指数化查询,现在是将条件直接拼接成了字符串,做了防注入处理,要改成使用参数化查询
  • 支持更多的方法解析成对应的 sql 语句