zoukankan      html  css  js  c++  java
  • 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实现的随笔,

  • 相关阅读:
    HDU 1394 Minimum Inversion Number
    LA 3938 动态最大连续和(线段树)
    HDU 1754 I Hate It(线段树)
    HDU 1166 敌兵布阵(线段树 or 二叉索引树)
    《乞力马扎罗的雪》读书笔记
    LA 3266 田忌赛马
    UVa 11235 频繁出现的数值
    《月亮与六便士》读书笔记
    LA 3135 阿格斯(优先队列)
    LA 3027 合作网络
  • 原文地址:https://www.cnblogs.com/Dah/p/886023.html
Copyright © 2011-2022 走看看