程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> 關於.NET >> 基於NBear的Domain層設計

基於NBear的Domain層設計

編輯:關於.NET

NBear是Teddy開發的快速開發框架,在之前的5個示例中,主要演示了主要的框架功能和業務領域模型不太復雜情形下忽略領域層的應用范例。但是,當業務模型相對復雜,單純基於簡單實體的強類型數據訪問接口,可能就會使得太多的業務邏輯被分散到service或facade層,此時,我們就最好加一層獨立的業務領域模型層來封裝實體和強類型接口的使用。本文為您演示基於NBear v1.6.0中新增的NBear.Domain的領域模型設計示例。

NBear.Domain

NBear.Domain主要為您提供了基類DomainModel和GuidKeyDomainModel,前者用於采用自增長ID主鍵的實體,後者用於采用Guid主鍵的實體。只需將他們作為你的領域類的基類,它就能提供最基本的領域類需要的CRUD等功能(包括Save, Delete, Find, FindAll等),您可以方便的以此為基礎進行擴展。

DomainModel.cs

 1using System;
 2using System.Data;
 3using System.Data.Common;
 4using System.Collections.Generic;
 5using System.Text;
 6using NBear.Common;
 7using NBear.Data;
 8
 9namespace NBear.Domain
10{
11  public interface IDomainModel<IEntityType, IEntityViewType>
12    where IEntityType : IEntity
13    where IEntityViewType : IEntity
14  {
15    void Save();
16    void Save(DbTransaction tran);
17    void LoadFromEntity(IEntityViewType entity);
18    object ID { get; }
19  }
20
21  public abstract class DomainModel<IEntityType, IEntityViewType, DomainType> : IDomainModel<IEntityType, IEntityViewType>
22    where IEntityType : IEntity
23    where IEntityViewType : IEntity
24    where DomainType : IDomainModel<IEntityType, IEntityViewType>, new()
25  {
26    Protected Members#region Protected Members
27
28    protected IEntityType entityValue;
29    protected IEntityType entityValue2;
30    protected IEntityViewType entityViewValue;
31
32    protected DomainModel()
33    {
34      entityValue = Gateway.Create<IEntityType>();
35      entityValue2 = Gateway.Create<IEntityType>();
36    }
37
38    /**//// <summary>
39    /// override this method in sub class to customly load auto-created key column id if neccessary
40    /// by default, when saving a new domain model, the latest auto created ID will be loaded.
41    /// </summary>
42    protected virtual void LoadCreatedID(DbTransaction tran)
43    {
44      KeyValueCollection keyValues = entityValue.GetKeyValues();
45
46      keyValues[0] = Gateway.Db.ExecuteScalar(tran, CommandType.Text, string.Format("select max([{0}]) from [{1}]", keyValues.GetKeys()[0], typeof(IEntityType).Name));
47    }
48
49    protected virtual void DoUpdate(DbTransaction tran)
50    {
51      string[] exceptColumns = Gateway.CompareEntities<IEntityType>(entityValue, entityValue2);
52      if (exceptColumns.Length == NBear.Common.Entity<IEntityType>.GetKeys().Length)
53      {
54        //no columns are modified, so no need to update
55        return;
56      }
57      KeyValueCollection keyValues = entityValue.GetKeyValues();
58      if (tran == null)
59      {
60        Gateway.Update<IEntityType>(keyValues.GetKeys(exceptColumns), keyValues.GetValues(exceptColumns), ID);
61      }
62      else
63      {
64        Gateway.Update<IEntityType>(keyValues.GetKeys(exceptColumns), keyValues.GetValues(exceptColumns), ID, tran);
65      }
66    }
67
68    protected virtual void DoCreate(DbTransaction tran)
69    {
70      string exceptKeyColumn = Entity<IEntityType>.GetKeys()[0];
71      if (tran == null)
72      {
73        DbTransaction t = Gateway.BeginTransaction();
74
75        try
76        {
77          Gateway.Insert<IEntityType>(entityValue, t, exceptKeyColumn);
78
79          LoadCreatedID(t);
80
81          t.Commit();
82        }
83        catch
84        {
85          t.Rollback();
86        }
87        finally
88        {
89          Gateway.CloseTransaction(t);
90        }
91      }
92      else
93      {
94        Gateway.Insert<IEntityType>(entityValue, tran, exceptKeyColumn);
95        LoadCreatedID(tran);
96      }
97    }
98
99    #endregion
100
101    Properties#region Properties
102
103    public IEntityType EntityValue
104    {
105      get
106      {
107        return entityValue;
108      }
109    }
110
111    public IEntityViewType EntityViewValue
112    {
113      get
114      {
115        return entityViewValue;
116      }
117    }
118
119    public virtual object ID
120    {
121      get
122      {
123        return entityValue.GetKeyValues()[0];
124      }
125    }
126
127    #endregion
128
129    Basic CRUD#region Basic CRUD
130
131    public virtual void LoadFromEntity(IEntityViewType entityView)
132    {
133      if (entityView == null)
134      {
135        return;
136      }
137      entityValue = Gateway.ConvertEntity<IEntityViewType, IEntityType>(entityView);
138      entityValue2 = Gateway.ConvertEntity<IEntityViewType, IEntityType>(entityView);
139    }
140
141    public void Save()
142    {
143      Save(null);
144    }
145
146    public virtual void Save(DbTransaction tran)
147    {
148      if (ID == null || Convert.ToInt32(ID) == 0)
149      {
150        DoCreate(tran);
151      }
152      else
153      {
154        DoUpdate(tran);
155      }
156
157      LoadFromEntity(Gateway.Get<IEntityViewType>(ID));
158    }
159
160    public static DomainType Find(object id)
161    {
162      DomainType obj = new DomainType();
163      obj.LoadFromEntity(Gateway.Get<IEntityViewType>(id));
164      return obj;
165    }
166
167    public static DomainType[] FindAll(string orderBy)
168    {
169      return EntityViewArrayToDomainArray(Gateway.SelectAll<IEntityViewType>(orderBy));
170    }
171
172    public static DomainType[] EntityViewArrayToDomainArray(IEntityViewType[] entityViews)
173    {
174      DomainType[] objs = new DomainType[entityViews.Length];
175      for (int i = 0; i < objs.Length; i++)
176      {
177        DomainType obj = new DomainType();
178        obj.LoadFromEntity(entityViews[i]);
179        objs[i] = obj;
180      }
181      return objs;
182    }
183
184    public static void Delete(object id)
185    {
186      Gateway.Delete<IEntityType>(id);
187    }
188
189    #endregion
190
191    Gateway#region Gateway
192
193    private static NBear.Data.Facade.Gateway _Gateway = null;
194
195    public static NBear.Data.Facade.Gateway Gateway
196    {
197      get
198      {
199        return (_Gateway == null ? GatewayManager.DefaultGateway : _Gateway);
200      }
201      set
202      {
203        _Gateway = value;
204      }
205    }
206
207    #endregion
208  }
209
210  public abstract class DomainModel<IEntityType, DomainType> : DomainModel<IEntityType, IEntityType, DomainType>
211    where IEntityType : IEntity
212    where DomainType : IDomainModel<IEntityType, IEntityType>, new()
213  {
214  }
215
216  public abstract class GuidKeyDomainModel<IEntityType, IEntityViewType, DomainType> : DomainModel<IEntityType, IEntityViewType, DomainType>
217    where IEntityType : IEntity
218    where IEntityViewType : IEntity
219    where DomainType : IDomainModel<IEntityType, IEntityViewType>, new()
220  {
221    protected override void DoCreate(DbTransaction tran)
222    {
223      //create guid
224      entityValue.GetKeyValues()[0] = Guid.NewGuid().ToString();
225
226      if (tran == null)
227      {
228        Gateway.Insert<IEntityType>(entityValue);
229      }
230      else
231      {
232        Gateway.Insert<IEntityType>(entityValue, tran);
233      }
234    }
235  }
236
237  public abstract class GuidKeyDomainModel<IEntityType, DomainType> : GuidKeyDomainModel<IEntityType, IEntityType, DomainType>
238    where IEntityType : IEntity
239    where DomainType : IDomainModel<IEntityType, IEntityType>, new()
240  {
241  }
242}

示例

首先,還是需要用NBear.Tools.EntityGen生成實體,這裡的數據庫還是采用的之前的示例Sample2中的數據庫TestRelation.mdb。

Entities.cs

1using System;
2using System.Collections.Generic;
3using System.Text;
4using NBear.Common;
5
6namespace Sample6.Entities
7{
8  public interface Group : IEntity
9  {
10    int ID { get; set; }
11    string Title { get; set; }
12    string Description { get; set; }
13    System.DateTime CreateTime { get; set; }
14    int ParentID { get; set; }
15  }
16
17  public interface Message : IEntity
18  {
19    int ID { get; set; }
20    int FromUserID { get; set; }
21    int ToUserID { get; set; }
22    string Title { get; set; }
23    string Content { get; set; }
24    System.DateTime SendTime { get; set; }
25  }
26
27  public interface User : IEntity
28  {
29    int ID { get; set; }
30    string Name { get; set; }
31    bool Gender { get; set; }
32    double Salary { get; set; }
33  }
34
35  public interface UserGroup : IEntity
36  {
37    int UserID { get; set; }
38    int GroupID { get; set; }
39  }
40
41  public interface vGroup : IEntity
42  {
43    int ID { get; set; }
44    string Title { get; set; }
45    string Description { get; set; }
46    System.DateTime CreateTime { get; set; }
47    int ParentID { get; set; }
48    int UserID { get; set; }
49  }
50
51  public interface vMessage : IEntity
52  {
53    int ID { get; set; }
54    int FromUserID { get; set; }
55    string FromUserName { get; set; }
56    int ToUserID { get; set; }
57    string ToUserName { get; set; }
58    string Title { get; set; }
59    string Content { get; set; }
60    System.DateTime SendTime { get; set; }
61  }
62
63  public interface vUser : IEntity
64  {
65    int ID { get; set; }
66    string Name { get; set; }
67    bool Gender { get; set; }
68    double Salary { get; set; }
69    int GroupID { get; set; }
70  }
71}

接著就能定義領域模型了,只需簡單的繼承DomainModel,你的類就擁有了基本的CURD接口,如下面的Message類,你也可以擴展你的類,為你的領域類擴充復雜的領域功能,使用OneToMany類,操作與當前類關聯的其他實體也非常便利,如這裡的Group和User類。

Domains.cs

1using System;
2using System.Collections.Generic;
3using System.Text;
4using NBear.Common;
5using NBear.Data.Facade;
6using NBear.Domain;
7
8namespace Sample6.Domains
9{
10  public class Group : DomainModel<Entities.Group, Entities.vGroup, Group>
11  {
12    private OneToMany<Entities.Group, Entities.vGroup, Entities.UserGroup, Entities.vUser> groupToUsers;
13
14    public override void LoadFromEntity(Sample6.Entities.vGroup entityView)
15    {
16      base.LoadFromEntity(entityView);
17
18      groupToUsers = new OneToMany<Entities.Group,Entities.vGroup,Entities.UserGroup,Entities.vUser>(Gateway.Db, "GroupID", entityValue, entityView);
19    }
20
21    public User[] FindUsersInGroup(string orderBy)
22    {
23      return (groupToUsers == null ? null : User.EntityViewArrayToDomainArray(groupToUsers.SelectMany(null, orderBy)));
24    }
25
26    public void AddUserToGroup(object userID)
27    {
28      if (groupToUsers == null)
29      {
30        return;
31      }
32
33      Entities.UserGroup userGroup = groupToUsers.CreateNewRelationEntity();
34      userGroup.UserID = (int)userID;
35      groupToUsers.InsertMany(userGroup);
36    }
37
38    public void DeleteUserFromGroup(object userID)
39    {
40      if (groupToUsers == null)
41      {
42        return;
43      }
44
45      groupToUsers.DeleteMany("[UserID] = @UserID", userID);
46    }
47  }
48
49  public class Message : DomainModel<Entities.Message, Entities.vMessage, Message>
50  {
51  }
52
53  public class User : DomainModel<Entities.User, Entities.vUser, User>
54  {
55    private OneToMany<Entities.User, Entities.vUser, Entities.Message, Entities.vMessage> fromUserToMessages;
56    private OneToMany<Entities.User, Entities.vUser, Entities.Message, Entities.vMessage> toUserToMessages;
57
58    public override void LoadFromEntity(Sample6.Entities.vUser entityView)
59    {
60      base.LoadFromEntity(entityView);
61
62      fromUserToMessages = new OneToMany<Entities.User, Entities.vUser, Entities.Message, Entities.vMessage>(Gateway.Db, "fromUserID", entityValue, entityView);
63      toUserToMessages = new OneToMany<Entities.User, Entities.vUser, Entities.Message, Entities.vMessage>(Gateway.Db, "toUserID", entityValue, entityView);
64    }
65
66    public Message[] FindSentMessages(string orderBy)
67    {
68      if (fromUserToMessages == null)
69      {
70        return null;
71      }
72
73      return Message.EntityViewArrayToDomainArray(fromUserToMessages.SelectMany(null, orderBy));
74    }
75
76    public Message[] FindReceivedMessages(string orderBy)
77    {
78      if (toUserToMessages == null)
79      {
80        return null;
81      }
82
83      return Message.EntityViewArrayToDomainArray(toUserToMessages.SelectMany(null, orderBy));
84    }
85  }
86}

ok,領域模型定義完了,下面就可以方便的使用以上類了:

Usage.cs

1using System;
2using System.Collections.Generic;
3using System.Data.Common;
4using System.Text;
5using NBear.Domain;
6using Sample6.Domains;
7using NBear.Data.Facade;
8
9namespace Sample6
10{
11  public class Usage
12  {
13    public static void Main()
14    {
15      //first you should set GatewayManager.DefaultGateway for all Domain Models before using them
16      GatewayManager.DefaultGateway = new Gateway(DatabaseType.MsAccess, @"Provider=Microsoft.Jet.OLEDB.4.0; Data Source=C:\Teddy\NBear\dist\Sample6\App_Data\TestRelation.mdb");
17
18      //if neccessary, you can set Specific Domain Models using specific Gateway instead of DefaultGateway
19      //Group.Gateway = ;
20      //Message.Gateway = ;
21      //User.Gateway = ;
22
23      //use Domain Models
24
25      //find group & users in group
26      Group group = Group.Find(1);
27      User[] usersInGroup = group.FindUsersInGroup("ID desc");
28
29      //modify and save group
30      //only modified properties will be in the update SQL which will be created behind domain model code
31      group.EntityValue.Description = "modified description";
32      group.Save();
33
34      //find user & delete from group
35      User user = usersInGroup[0];
36      Message[] sentMessages = user.FindSentMessages("SendTime desc");
37      group.DeleteUserFromGroup(user.ID);
38
39      //create new user & add to group
40      User newUser = new User();
41      newUser.EntityValue.Name = "new user";
42      newUser.EntityValue.Salary = 1000;
43      newUser.EntityValue.Gender = false;
44      newUser.Save();
45      group.AddUserToGroup(newUser.ID);
46
47      //modify user salary, save & send message in a transaction
48      DbTransaction tran = User.Gateway.BeginTransaction();
49      try
50      {
51        user.EntityValue.Salary = 99999;
52        user.Save(tran);
53
54        Message msg = new Message();
55        msg.EntityValue.Title = "new msg";
56        msg.EntityValue.Content = "salary changed";
57        msg.EntityValue.FromUserID = user.EntityValue.ID;
58        msg.EntityValue.ToUserID = 3;
59        msg.EntityValue.SendTime = DateTime.Now;
60        msg.Save(tran);
61
62        tran.Commit();
63      }
64      catch
65      {
66        tran.Rollback();
67        throw;
68      }
69      finally
70      {
71        User.Gateway.CloseTransaction(tran);
72      }
73
74      //if you want to access more user's value than its basic value, you can access user.EntityViewType, which is its view entity - vUser
75      int groupIDOfUser = user.EntityViewValue.GroupID;
76    }
77  }
78}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved