NSweetie是一个轻量, 高效, 方便的数据访问组件. 用户创建好数据库后, 只需要提供数据操作的接口定义, 输入什么参数以及得到什么数据或实体, 其他的事情全部交给NSweetie吧! 组件不是魔法, 依然需要生成代码, NSweetie生成的代码的方式是通过System.Reflection.Emit的API直接生成MSIL, 用户看不到任何CSharp代码.. 其实, 也不需要看到.. 当需求变化时, 修改接口定义和业务实现, 编译, 启动程序, OK, finish.

截止到现在, NSweetie的主要功能有:

1. 按实体抽象类定义自动实现具有Insert, Delete, Update方法的实体对象;
2. 支持执行IDbCommand或SQL语句映射到实体对象, 实体列表或基本类型数据, 实体对象常用的CRUD操作;
3. Query Method: 支持查询到方法/属性的映射, 查询可以是SQL语句, 也可以是存储过程, 查询方法支持方法参数绑定以及对象属性绑定;
4. 支持所有System.Data.DbType中绝大多数的数据类型映射, 对于可空的数据列也提供了相应的Nullable<T>数据类型支持.
5. 支持自定义数据库Provider, 方便支持多种数据库系统.

一些代码示例:

/* 一个实体的定义 */

[Table]

public abstract class Person : EntityBase

{

    [Column(IsPrimaryKey = true, CanInsert = false /* 主键通过DB数据库生成, 保存实体时不作为参数 */)]

    public abstract int PersonID { get; set; }

 

    [Column]

    public abstract string LastName { get; set; }

 

    [Column]

    public abstract string FirstName { get; set; }

 

    [Column] /* 支持Nullable类型 */

    public abstract DateTime? HireDate { get; set; }

 

    [Column]

    public abstract DateTime? EnrollmentDate { get; set; }

 

    /* 一个典型的查询方法(属性)

    * 因为现在还不支持多对多的关系的映射, 所以通过查询方法实现,

    * NSweetie将为用户实现此方法

    * 注意SQL语句中的"@this.PersonID", 参数会在方法执行时绑定到该对象的PersonID属性

    */

    [Query("select * from Course where CourseID in " +

           "(select CourseID from CourseInstructor where PersonID = @this.PersonID)")]

    public abstract List<Course> Courses { get; }

}



/* 使用抽象类来定义实体, 可以在实体中实现自定义的业务逻辑 */

[Table]

public abstract class ImageData : EntityBase

{

    [Column(IsPrimaryKey = true, CanInsert = false)]

    public Guid ImageDataID { get; set; }

 

    [Column]

    public string Title { get; set; }

 

    [Column]

    public byte[] RawData { get; set; }

 

    /* 自定义的属性 */

    public Bitmap Image

    {

        get

        {

            return (Bitmap)Bitmap.FromStream(new MemoryStream(RawData));

        }

        set

        {

            MemoryStream ms = new MemoryStream();

            value.Save(ms, ImageFormat.Jpeg);

            RawData = ms.ToArray();

        }

    }

}



/* 一个QueryClass, 定义了一些数据操作  */

public abstract class MyQuerys : QueryBase

{

    /* 支持存储过程的查询方法 */

    [Query("sp_addPerson", IsStoredProcedure = true)]

    public abstract void AddPersonUsingSp(

        string lastName,

        string firstName,

        DateTime hireDate,

        DateTime enrollmentDate);

 

    /* 一般的SQL语句调用 */

    [Query("select count(*) from Person")]

    public abstract int GetPersonCount();

 

    [Query] /* 默认是存储过程调用, 返回值支持常用的基本类型, 实体, 实体列表

             * output参数将使用ref语法 */

    public abstract int TestOut(ref int value);

 

    [Query] /* 属性也可以作为一个存储过程的调用 */

    public abstract List<Person> AllPerson { get; }

}


定义了一堆东西, 怎么用呢? 其实也很简单:

class Program

{

    static void Main(string[] args)

    {

        /* 获取默认的DatabaseProxy对象, 数据库相关设置从config文件中读取 */

        var db = DatabaseProxy.Default;

        var p = db.NewObject<Person>();

        p.FirstName = "Adrian";

        p.LastName = "Huang";

        p.Insert(); // 保存!

 

        var imageData = db.SelectOneWhere<ImageData>("title = 'view'");

        imageData.Image.Save(@"C:\img.jpg", ImageFormat.Jpeg);

        imageData.Delete(); // 删除!

 

        /* 获取QueryObject */

        var myQuerys = db.GetQueryObject<MyQuerys>();

 

        /* 调用它的方法 */

        Console.WriteLine(myQuerys.GetPersonCount());

 

        p = db.SelectOneWhere<Person>("firstname = 'Monica'");

 

        /* 这样实现的多对多关系似乎不是很好看:

            [Query("select * from Course where CourseID in " +

                    "select CourseID from CourseInstructor where PersonID = @this.PersonID)")]

            public abstract List<Course> Courses { get; }

        */

        foreach (var c in p.Courses)

        {

            Console.WriteLine(c.Title);

        }

    }

}


NSweetie的开发依然在进行中, 上面的代码几乎展示了NSweetie现在所有实现的feature, NSweetie现在还比较弱..希望大家多提一些意见和建议, 当它足够成熟的时候我会提供源码供大家下载学习和使用的.
另外, 如果大家有兴趣, 我将会写一点有关NSweetie实现的随笔,

Posted on 2007-09-07 17:20 Adrian H. 阅读(1997) 评论(10)  编辑 收藏 所属分类: MiscC#.Net Framework / CLRDatabase

Feedback

#1楼    回复  引用  查看    

2007-09-07 17:55 by 户籍民警      
n年前就有了

#2楼    回复  引用  查看    

2007-09-07 20:15 by 金色海洋(jyk)      
不好意思,每台看懂。

@ 户籍民警
n年前就有这个了吗?太厉害了。

#3楼    回复  引用  查看    

2007-09-07 21:33 by 亚历山大同志      
这样子定义感觉有点怪怪的

#4楼    回复  引用  查看    

2007-09-07 23:01 by 真水无香.chen      
关注中~~~~支持你

#5楼    回复  引用  查看    

2007-09-08 15:46 by micYng      
既然还要用到 var 这个东东,还不如直接用linq,而且拼凑sql语句似乎也没有类型安全

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

2007-09-08 19:18 by Adrian H.      
@micYng
NSweetie是支持.NET 2.0的, 用3.0的语法不一定就得部署到.NET 3.5的环境中去..
这个组件是轻量高性能的, 且没有.NET 3.5的依赖, LINQ To SQL是个很完备强大的东西, 功能上当然没的比.. 但NSweetie能满足绝大多数的功能需要, 简单的行为直接通过调用DatabaseProxy的方法就能实现, 复杂的行为则通过调用自动实现的Stored Procedure方法来实现.

#7楼    回复  引用  查看    

2007-09-09 11:55 by 亚历山大同志      
@Adrian H.
提供一个可供下载的版本和一个性能测试的结果吧,这样子更加具备说服力

#8楼    回复  引用  查看    

2007-09-10 12:07 by Clark Zheng      
标题不错

#9楼    回复  引用    

2007-09-10 16:33 by Adrian Huang [未注册用户]
@Clark Zheng
呵呵~
被“传媒”的气氛影响了。。

这个东西功能跟LINQ等ORM工具完全不能比。。比较性能虽然没什么意义。。
但我粗略测试了一下。。NSweetie的性能是LINQ性能到2~5倍。。。
不过另我惊讶的是LINQ的Select性能原来挺不错的。。。

#10楼    回复  引用  查看    

2007-11-29 13:30 by woog      
你的css滤镜把文字都搞的模糊不清了。看文章真费劲。。。

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


相关链接: