NSweetie: 访问数据也能这样甜蜜预告篇

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实现的随笔,

原文地址:https://www.cnblogs.com/Dah/p/886023.html