• 实现类似LINQ TO SQL的功能, 轻量级的数据访问组件


    LINQ TO SQL作为一个对SQL Server特性完全支持的数据访问组件, 强大也是要付出性能代价的, 于是我想自己实现一个类似的组件, 这两天连续设计和编码, 基本实现了预定的功能, 包括对定义的实体的CRUD操作, 存储过程的代码生成. 组件的使用者只需要编写类, 定义实体的各个属性以及对应表, 列属性, 组件可以动态生成从SqlDataReader到实体的映射代码, 所谓动态是通过在运行时Emit IL, 获取这一段映射的代码, 通过良好的类层次设计只需要Emit所需要的很少量的中间代码, 对于一个实体类型只需要生成一次再缓存起来, 许多Emit过程所必要的对象都缓存在了static字段中, 所以Emit的过程是很高效的, 使用Profiler可以看到生成一个对于的类型只需要几十ms~100ms左右; 对于存储过程, 用户提供一个存储过程对于的接口, 组件将提供一个实现该接口的对象, 用户则可以使用它很方便的调用存储过程.

    一些示例代码如下 (代码是C# 3.0的, 类型推导让人少写许多类型参数, very sweet :)

    /* 存储过程接口定义, 通过Attribute实现一些必要的定义 */
    public interface IStoredProcedures
    {
        [StoredProcedure]
        
    int Echo([Parameter("pa")]int ppaa);

        [StoredProcedure]
        List
    <BlogEntity> GetBlogs(int count);

        [StoredProcedure]
        
    void TestOut([Parameter(Size = 10)]out string oc);
    }

    class SampleProgram
    {
        
    static void Main(string[] args)
        {
            DatabaseProxy db 
    = new DatabaseProxy("server=localhost; database=TestDB; integrated security=true");
            
            BlogEntity entity 
    = new BlogEntity("yep"123);

            
    /* 保存实体 */
            db.Insert(entity); 

            entity.Title 
    = "nope";

            
    /* 更新实体 */
            db.Update(entity);

            
    /* 基本的条件和排序, 支持Expression的嵌套分析, 类似Lambda Expression, 但要轻量不少  */
            BlogEntity blog 
    = db.SelectOne<BlogEntity>(What.All, Where.Equal("CommentsCount"123), null);

            
    /* 删除实体 */
            db.Delete(entity);
            
            
    /* 返回实体列表的查询 */
            List
    <BlogEntity> list = db.Select<BlogEntity>(What.All, Where.Between("CommentsCount"1030), Order.By("Title").Desc.And("CommentsCount"));

            
    foreach (BlogEntity b in list)
            {
                Console.Write(b.Title 
    + "" + b.CommentsCount + "\n");
            }

            
    /* 根据定义的接口, 实现存储过程 */
            var procs 
    = db.GetStoredProcedureObject<IStoredProcedures>();
            
            
    /* 返回基本类型或实体 */
            
    int ret = procs.Echo(2);

            
    /* 返回实体列表 */
            list 
    = procs.GetBlogs(10);

            
    string str = string.Empty;
            
    /* 支持Output参数 */
            TestOut(
    out str);
        }
    }

    现在主要要做的工作想想似乎有很多:
    1. 对Select功能的增强
    2. 支持主外键的联合及实体继承, 组合, 连接
    3. 继续优化IL生成和实现方式
    4. 参数validating和exception handling
    5. 数据库元数据到实体代码, 存储过程接口定义的代码生成(消除一切冗余的工作!)

    别忘了, 这是个轻量, 并希望是个高效的一个ORM/数据访问组件... 不想把他弄得太复杂, 功能完全的有很多, 除了LINQ TO SQL, NBear做得也很好啊~
  • 相关阅读:
    Message "'OFFSET' 附近有语法错误。 在 FETCH 语句中选项 NEXT 的用法无效。" 解决办法 EntityFrameworkCore
    关于.Net Core 部署在Linux下连接SqlServer数据库超时解决办法
    EntityFrameworkCore Db First 生成Model时出错 PowerShell 版本过低
    八大排序算法详解(动图演示 思路分析 实例代码java 复杂度分析 适用场景)
    Loadrunner12 使用谷歌浏览器录制脚本时打不开网页-解决办法
    Loadrunner12 在谷歌浏览器录制https协议的脚本时,提示不是私密链接-解决办法
    loadrunner回放https请求时报connect 时发生ssl协议错误--解决办法
    百度2020春招 笔试算法题第一题 需要买多少瓶果汁
    美团2020春招 笔试算法题 双行道
    美团2020春招 笔试算法题 最好一样
  • 原文地址:https://www.cnblogs.com/Dah/p/869081.html
Copyright © 2020-2023  润新知