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}