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做得也很好啊~
Posted on 2007-08-25 09:05 Adrian H. 阅读(868) 评论(7)  编辑 收藏 所属分类: C#Database

Feedback

#1楼    回复  引用  查看    

2007-08-26 01:36 by 代码乱了      
其实可以放到首页去的哦,这样可以让大家来讨论一下
另外没有看到你的实现过程,遗憾

#2楼    回复  引用  查看    

2007-08-26 13:31 by Lostinet      
支持

#3楼    回复  引用    

2007-08-27 13:14 by Adrian H. [未注册用户]
@代码乱了
现在的代码要实现那些扩展功能需要整体的重构... 完成后再发文叙述有关实现的部分.

#4楼    回复  引用    

2007-08-27 14:06 by Adrian H. [未注册用户]
@Lostinet
:) 很期待你的CSPAbstractRecord哦~

#5楼    回复  引用  查看    

2007-08-28 08:34 by 代码乱了      
@Adrian H.
期待……

#6楼    回复  引用  查看    

2007-08-28 21:22 by 宋国安      
个人觉得没有必要再去搞这个。.已经有人推出了,那就去使用它.如果你提出的东西能超越它,至少有能技之长,要不然,还是用现成的。

#7楼 [楼主]   回复  引用  查看    

2007-08-28 22:29 by Adrian H.      
@宋国安
是的, 已经有许多很完整的框架等着人去用, LINQ的功能的确很完整了, 但我觉得它还是不适合我自己, 只是想设计一个符合自己思路的东西, 在实现它的过程中也许能发现更多的东西...

标题  
姓名  
主页
Email (只有博主才能看到) 
验证码 *  看不清,换一张 [登录][注册]
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2007-08-25 14:26 编辑过


相关链接: