zoukankan      html  css  js  c++  java
  • NBearV3.0.0 Preview发布 全新ORM实现![11/1 更新:全面支持实体属性级联更新]

    11/1 更新:全面支持实体属性级联更新,详见下面的案例的Entity Usage UnitTests代码。

    今天发布了NBear的全新版本V3的Preview。

    感兴趣的朋友可以从http://sf.net/projects/nbear下载最新源码。

    NBearV3相对于V2作了巨大升级和改进。因此不兼容于NBearV2。

    之所以目前称为Preview版是因为新版本的源码中除了包含基于NBearV3重写的SimpleGuestbookV1.1之外,还没有任何相关使用文档,并且,实体生成工具仅支持C#,还不支持直接生成VB.NET代码。我会在近期不断补充,并于年内发布V3的正式版。

    NBearV3新增/修改功能列表:

    1、完全重新设计的ORM实现,支持实体继承,实体间复杂关联(一对一、一对多、多对多)及透明的级联插入、更新、删除,LazyLoad等。
    2、提供用于整个开发过程的更易使用的代码生成工具,支持:实体设计代码、实体代码、实体配置文件和数据库创建脚本生成。
    3、精简优化了底层数据访问代码,进行了更细致的单线程/多线程性能测试。
    4、实体及关联关系可以使用任意标准的.Net Framework支持的语言,使用interface、Attribute、接口继承等语言的自然元素作为实体设计元数据,并使用VS.NET2005的类设计器进行设计。
    5、自动生成的实体类是标准的class,避免了V2中基于Emit生成代码的性能损失和可能的内存泄露,集成用于强类型查询的查询代码到每个实体类,并支持标准的各种系统序列化(XML,Binary,WebService SOAP)。生成的实体类代码不依赖于实体设计元数据。
    6、对于ServiceFactory部分,增加了SerializationManager类,用于增加自定义类型序列化实现,从而使得service能够支持任意类型的自定义参数和返回值。
    7、重新优化设计的Gateway类,新增PageSelector强类型数据分页器,强/弱类型数据访问,批处理数据访问更简洁高效。
    8、NBear.Web模块中,删除了UrlRewrite模块。因为,这样的模块市面上太多了,有些也很强大,因此NBear没必要内置一个轻量级实现了。

    -

    ORM案例演示

    这里演示的案例代码包含于源代码中的NBear.Test.CaseTests程序集,演示了一组包含继承关系、复杂关联关系、复合数据类型、枚举类型的实体。

    所有的实体关系图如下:



    以上的实体关系图是标准的VS2005 IDE的类设计器对于实际的实体设计代码的直观反映。其中User、AgentUser、LocalUser为一组有继承关系的实体。UserProfile为和所有User一对一关联的Profile信息。Group为和所有User多对多关联的Group,UserGroup为关联实体,除了包含用于关联的字段之外,还可以包含多个Weight属性。Domain为和AgentUser和LocalUser关联的Domain,它也是一个多对多关系,关联实体为AgentUserDomain。同时,关联实体支持被关联的实体是多主键的情形。另外,User.Name为一个包含FirstName和LastName字段的struct,这个复合类型映射到一个名为Name的string字段,如何序列化和反序列化这个struct可自定义,而User.Status为一个枚举类型,映射到一个int类型的Status数据字段。

    完整的实体设计代码如下:

    Entity Design Code

    注意,所有的设计实体都使用接口表示,并使用必要的Attribute进行修饰。关于如何使用这些Attribute,近期我会有独立的文档描述,这里大家可以直观感受一下。每个属性的SqlType属性并不是必须的,如果不指定,则代码生成工具将会根据属性的.Net类型使用默认值,特别是对于数值类型,字符串类型建议自定义长度,否则默认为nvarchar(127)。

    注意,这里列出的是设计实体代码,所有最终的实际实体(和用于设计的这些代码没有任何依赖来关系)、相关配置信息和数据库生成脚本都能够基于以上设计代码由NBear提供的工具自动生成。生成的具体的代码,我就不演示了。下面简单列举用于操作这些实体的测试代码,包括CRUD和Transaction(11/1更新支持实体属性级联更新,保留更改前的测试代码为黄色,更改后的代码用正常颜色表示)。

    以下是支持属性级联更新前的测试代码:

    Entity Usage UnitTests

    以下是11/1支持级联更新后的代码:

      1using System;
      2using System.Data.Common;
      3using System.Text;
      4using System.Transactions;
      5using System.Collections.Generic;
      6using Microsoft.VisualStudio.TestTools.UnitTesting;
      7
      8using Entities;
      9using NBear.Common;
     10using NBear.Data;
     11
     12using NBear.Test.CaseTests.shared;
     13
     14namespace NBear.Test.CaseTests
     15{
     16    [TestClass]
     17    public class CaseTest
     18    {
     19        Additional test attributes
     47
     48        [TestMethod]
     49        public void TestCreate()
     50        {
     51            LocalUser newLocalUser = new LocalUser();
     52            newLocalUser.ID = Guid.NewGuid();
     53            newLocalUser.LoginName = newLocalUser.ID.ToString();
     54            UserName name = new UserName();
     55            name.FirstName = "first name of local user";
     56            name.LastName = "last name of local user";
     57            newLocalUser.Name = name;
     58            newLocalUser.Password = "password";
     59            newLocalUser.Status = UserStatus.Normal;
     60
     61            gateway.Save<LocalUser>(newLocalUser);
     62        }

     63
     64        [TestMethod]
     65        public void TestFind()
     66        {
     67            AgentUser[] users = gateway.FindArray<AgentUser>(WhereClip.All, OrderByClip.Default);
     68        }

     69
     70        [TestMethod]
     71        public void TestUpdate()
     72        {
     73            LocalUser user = gateway.FindArray<LocalUser>(WhereClip.All, LocalUser._.Password.Desc)[0];
     74            user.Password = "12345";
     75            UserName newName = new UserName();
     76            newName.FirstName = "12345";
     77            user.Name = newName;
     78            gateway.Save<LocalUser>(user);
     79            user = gateway.Find<LocalUser>(user.ID);
     80            Assert.AreEqual(user.Password, "12345");
     81            Assert.AreEqual(user.Name, newName);
     82        }

     83
     84        [TestMethod]
     85        public void TestDelete()
     86        {
     87            LocalUser newLocalUser = new LocalUser();
     88            newLocalUser.ID = Guid.NewGuid();
     89            newLocalUser.LoginName = newLocalUser.ID.ToString();
     90            UserName name = new UserName();
     91            name.FirstName = "first name of local user";
     92            name.LastName = "last name of local user";
     93            newLocalUser.Name = name;
     94            newLocalUser.Password = "password";
     95            newLocalUser.Status = UserStatus.Normal;
     96
     97            gateway.Save<LocalUser>(newLocalUser);
     98
     99            Guid id = newLocalUser.ID;
    100            AgentUser user = gateway.Find<AgentUser>(id);
    101            gateway.Delete<AgentUser>(user);
    102            Assert.IsNull(gateway.Find<User>(id));
    103            Assert.IsNull(gateway.Find<AgentUser>(id));
    104            Assert.IsNull(gateway.Find<LocalUser>(id));
    105        }

    106
    107        private Guid CreateSampleData(DbTransaction tran)
    108        {
    109            //create local user
    110            LocalUser newLocalUser = new LocalUser();
    111            newLocalUser.ID = Guid.NewGuid();
    112            newLocalUser.LoginName = newLocalUser.ID.ToString();
    113            UserName name = new UserName();
    114            name.FirstName = "first name of local user";
    115            name.LastName = "last name of local user";
    116            newLocalUser.Name = name;
    117            newLocalUser.Password = "password";
    118            newLocalUser.Status = UserStatus.Normal;
    119
    120            //create user profile
    121            UserProfile newUserProfile = new UserProfile();
    122            newUserProfile.ContentXml = "sample content xml";
    123            newUserProfile.UserID = newLocalUser.ID;
    124
    125            newLocalUser.Profile = newUserProfile;
    126
    127            //create group
    128            Group newGroup = new Group();
    129            newGroup.ID = Guid.NewGuid();
    130            newGroup.IsPublic = true;
    131            newGroup.Name = newGroup.ID.ToString();
    132
    133            newLocalUser.Groups = LocalUser.AddArrayItem<Group>(newLocalUser.Groups, newGroup);
    134
    135            //create domain
    136            Domain newDomain = new Domain();
    137            newDomain.Desc = "sample domain desc";
    138            newDomain.ID = Guid.NewGuid();
    139            newDomain.Name = "sample domain name";
    140
    141            newLocalUser.Domains = LocalUser.AddArrayItem<Domain>(newLocalUser.Domains, newDomain);
    142
    143            gateway.Save<LocalUser>(newLocalUser, tran);
    144
    145            return newLocalUser.ID;
    146        }

    147
    148        [TestMethod]
    149        public void TestAsp20Transaction()
    150        {
    151            Guid id = default(Guid);
    152            using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))
    153            {
    154                id = CreateSampleData(null);
    155
    156                scope.Complete();
    157            }

    158
    159            AgentUser user = gateway.Find<AgentUser>(id);
    160            Assert.AreNotEqual(user.Domains[0], null);
    161            Assert.AreNotEqual(user.Groups[0], null);
    162            Assert.AreNotEqual(user.Profile, null);
    163
    164            user.Status = UserStatus.Deleted;
    165            user.Profile.ContentXml = "modified";
    166
    167            gateway.Save<AgentUser>(user);
    168            AgentUser anotherThisUser = gateway.Find<AgentUser>(user.ID);
    169            Assert.AreEqual(anotherThisUser.Status, user.Status);
    170            Assert.AreEqual(anotherThisUser.Profile.ContentXml, user.Profile.ContentXml);
    171
    172            gateway.Delete<User>(user);
    173            Assert.IsNull(gateway.Find<LocalUser>(id));
    174            Assert.IsNull(gateway.Find<UserProfile>(id));
    175        }

    176
    177        [TestMethod]
    178        public void TestAsp11Transaction()
    179        {
    180            Guid id = default(Guid);
    181            DbTransaction tran = gateway.BeginTransaction();
    182            try
    183            {
    184                id = CreateSampleData(tran);
    185
    186                tran.Commit();
    187            }

    188            catch
    189            {
    190                tran.Rollback();
    191            }

    192            finally
    193            {
    194                gateway.CloseTransaction(tran);
    195            }

    196
    197            AgentUser user = gateway.Find<AgentUser>(id);
    198            Assert.AreNotEqual(user.Domains[0], null);
    199            Assert.AreNotEqual(user.Groups[0], null);
    200            Assert.AreNotEqual(user.Profile, null);
    201
    202            user.Status = UserStatus.Deleted;
    203            user.Profile.ContentXml = "modified";
    204
    205            gateway.Save<AgentUser>(user);
    206            AgentUser anotherThisUser = gateway.Find<AgentUser>(user.ID);
    207            Assert.AreEqual(anotherThisUser.Status, user.Status);
    208            Assert.AreEqual(anotherThisUser.Profile.ContentXml, user.Profile.ContentXml);
    209
    210            gateway.Delete<User>(user);
    211            Assert.IsNull(gateway.Find<LocalUser>(id));
    212            Assert.IsNull(gateway.Find<UserProfile>(id));
    213        }

    214    }

    215}

    注意比较CreateSampleData()和TestXXXTransaction()方法的代码。可以看到,支持属性级联更新后,操作实体及关联属性的代码极大简化了!

    //本文结束

  • 相关阅读:
    java内部类
    navicat使用教程-PJ
    提交代码时的注意事项
    多线程技术
    Apache POI使用详解
    网站链接收藏夹
    MySQL优化
    Oracle创建用户、角色、授权、建表
    oracle 安装提示未找到文件安装
    Json对象与Json字符串的转化、JSON字符串与Java对象的转换
  • 原文地址:https://www.cnblogs.com/teddyma/p/545885.html
Copyright © 2011-2022 走看看