' y V" `: ~4 s! j% I: | FileStream fs = new FileStream(filename, FileMode.Open);% t) \8 ^" a) Y+ Q% H. I
& u5 J9 j4 M7 w! R. w1 b5 N PurchaseOrder po; + P* h* N3 k/ f( h po = (PurchaseOrder)serializer.Deserialize(fs);. O y; W9 F" Z9 i9 u8 K
PurchaseOrderPrinter.PrintPurchaseOrder(po); $ Z' J u2 e& N4 k } - @, B) i8 R/ B# |' j0 u h 8 D; b8 o' T4 P, l" e. r- T. }7 n7 u9 K% Y. n* c I7 K
private static void serializer_UnknownNode * B5 {* V l! T& c/ P- ^. | (object sender, XmlNodeEventArgs e) { 1 p1 V$ J# {; F E: V q9 Y Console.WriteLine("Unknown Node:" + e.Name + "\t" + e.Text); ! r( s$ B' V! r) O }" C" M$ R/ K8 [9 e0 D1 R$ k5 u* z
' V. ?# Y2 m' b) N8 g* y
private static void serializer_UnknownAttribute4 |3 D9 z" Q! C' g/ Q+ S
(object sender, XmlAttributeEventArgs e) {- _; e& n* R9 I2 I7 N1 M
System.Xml.XmlAttribute attr = e.Attr; d& s3 R) d# F2 b0 B0 I4 Q
Console.WriteLine("Unknown attribute " + ( a8 w! f" k' F% g9 o8 T attr.Name + "='" + attr.Value + "'");6 O9 M1 F5 r2 m1 a$ e
}2 _/ U: g5 Y2 a4 n3 a
9 @ g6 m" v$ o- f8 P
private static class PurchaseOrderPrinter {: m+ o4 m" J& s
public static void PrintPurchaseOrder(PurchaseOrder po) { ' R& D! Z) F- T7 r+ f+ l PrintOrderDate(po);: _: a1 U1 p5 }4 e/ M: U; C* j1 p
PrintAddress(po.ShipTo); ( O) l3 p6 V: t( [" t0 O3 f1 K PrintOrderedItem(po.OrderedItems);, \& S) ?. I4 x2 i* G
PrintOrderCost(po); / d1 P0 ^# K) c } , ]# T+ \ Y% E- y. V2 S/ N ]* o9 ^$ T5 j* G9 h R
private static void PrintOrderCost(PurchaseOrder po) { 9 o/ D- _7 L& ~! y$ ~ Console.WriteLine("\t\t\t\t\t Subtotal\t" + po.SubTotal);; Y5 D- u% {- A1 L
Console.WriteLine("\t\t\t\t\t Shipping\t" + po.ShipCost); 7 S% v0 } u6 g1 s3 X Console.WriteLine("\t\t\t\t\t Total\t\t" + po.TotalCost); 9 _/ S$ e& c$ I! u t7 R } ( }6 x/ ^8 J, V' V 0 ], _ u% A% E( v6 m# W0 H# { private static void PrintOrderDate(PurchaseOrder po) {5 }# h7 o2 B# {8 A- n; x
Console.WriteLine("OrderDate: " + po.OrderDate);" q* i8 v# q8 k4 j2 P. W
}+ G q, I9 f% R+ [5 G2 }6 s
4 @1 e( U7 t1 V private static void PrintOrderedItem(OrderedItem[] items) {; r% ~# ~1 ^+ |2 t! ?+ }
Console.WriteLine("Items to be shipped:"); . m9 L: X; ]) [% f% Q+ A( n0 S foreach (OrderedItem oi in items) {: w. _' G! K5 r" s
Console.WriteLine("\t" + : f( U' b5 w5 V8 w1 E# |" w$ ^5 `; Q( ^ oi.ItemName + "\t" + 7 t2 A* I Y3 G6 x) r# o oi.Description + "\t" +( A" a. X7 b. E: k- d9 G6 Z* k, j. O- O
oi.UnitPrice + "\t" +. P& h7 F+ h( f, k& g( Q. {
oi.Quantity + "\t" + + F/ F" A7 K5 j$ t( J1 U oi.LineTotal);9 i7 u; A; B0 J7 M2 i. E- y& V
} , f/ [; c( E) E0 I' I3 |; A/ F } * {* F- j, c( E) G0 L0 C( {, I: F; H
private static void PrintAddress(Address a) {; z( p! Y& x. q% B- ?
// Read the fields of the Address object.; q, e- L" \6 s3 `- D- F
Console.WriteLine("Ship To:");2 i( `3 ] @0 E; x% p. V
Console.WriteLine("\t" + a.Name);* T# Y+ T4 n/ k
Console.WriteLine("\t" + a.Line1);5 n& ` _( B A, Y, w$ R2 U. d
Console.WriteLine("\t" + a.City); 5 Z. J' D2 I/ |' Y2 ^3 S Console.WriteLine("\t" + a.State); ) `% f9 `: l! { Console.WriteLine("\t" + a.Zip); + Y$ t& _ s% m4 a/ } Console.WriteLine(); ; `/ K5 w$ w8 w- ~9 Q+ g* |# L }* o: M3 s2 Z2 R3 e$ f3 W0 ]
}) \) J- g9 z3 I# l5 ?4 t1 ?" }
}0 z* b; p/ {0 G& ~- m2 p6 H
3 P/ v$ u" l& C8 ?
5 O7 o8 F5 F9 a6 _8 E9 O( w& ~ & Q' s! a% Q( o" w+ m5 ^5 i阅读代码时,我们可以先关注最主要的方法,即CreatePurchaseOrder()和ReadPurchaseOrder()方法。如果并不希望了解过多构造PO对象的细节,通过阅读这样简短的方法,可以很容易地抓住这两个方法的实现,那就是通过构建一个PO对象,进行序列化,而在反序列化时,将获得的PO对象信息打印出来。% O: `* [1 S0 b9 Y. d' P+ A$ ~
其实,糟糕的代码不一定就是初学者的“专利”,让我们看看NHibernate中的一段代码:public SessionFactoryImpl(Configuration cfg, IMapping mapping, Settings settings, EventListeners listeners)2 D" t, `1 o& D5 j6 ~
{ 0 c5 q5 ?" d5 s1 O) H Init(); 8 W' h( }2 G' }* H3 s, @ log.Info("building session factory");: i1 f4 C- \, i2 B, _& R+ J& e7 C
4 i2 f7 }0 ^4 X1 ^$ _4 A; C% _! i% s
properties = new Dictionary<string, string>(cfg.Properties);3 _* e8 m5 l+ T9 r
interceptor = cfg.Interceptor;4 L' W* r: r# R# N
this.settings = settings; 4 X3 [9 D1 K: W: g0 e sqlFunctionRegistry = new SQLFunctionRegistry(settings.Dialect, cfg.SqlFunctions);1 Y" `# c# @# Q, ~# a
eventListeners = listeners; 4 [; M5 h- M, S. y0 B" ?* [ filters = new Dictionary<string, FilterDefinition>(cfg.FilterDefinitions); ) z. N! @/ t$ s& d. a+ \+ Y if (log.IsDebugEnabled)* k6 u! l& y7 |
{8 A$ I3 @. u- W7 v
log.Debug("Session factory constructed with filter configurations : " + CollectionPrinter.ToString(filters)); . X9 i: ?/ `$ h } 3 e% K& F7 I( \6 |% K% l. f$ c6 U3 ~! i) a. E+ `( T
if (log.IsDebugEnabled) 2 a" \" R2 F0 n; k* m { . U" j* v9 }" y0 ]$ n( a9 K7 y6 R log.Debug("instantiating session factory with properties: " + CollectionPrinter.ToString(properties));: v$ n: o1 Y& s9 @2 U3 E9 o% |+ b
} # @' H' K0 W0 \6 c , C7 B- M- j2 x# t; Y+ _ try ' M/ [4 G& B1 M- u3 y: w { # ^ ^5 h" y e) a' Z% j if (settings.IsKeywordsImportEnabled) 1 h8 k7 C% A; }; H8 J { 1 l/ e7 E6 d8 J' \+ I/ D$ l: N SchemaMetadataUpdater.Update(this); / T3 G7 ?( D. W; w } * P+ U/ B6 C, e4 S+ Y if (settings.IsAutoQuoteEnabled)4 B: S5 f* Y8 T/ K7 m+ x
{ 1 \5 h% M6 s( N& v8 j SchemaMetadataUpdater.QuoteTableAndColumns(cfg); ; f; Z$ P% g$ B9 Y2 q1 L% d. `3 j } 7 J5 m, Y, X" w( t" w } $ t( T, G$ r* Y1 f' D catch (NotSupportedException) / L' k) a, H1 z, r3 Y { 1 a% P! V! l" z // Ignore if the Dialect does not provide DataBaseSchema ' u) ]; ?% v" o7 a# y5 Z
} - y4 F% D" C' z5 k& | i; W: {& f0 }. K$ [. }. `1 k #region Caches 3 a( X- f _& B2 B! B: m0 S# r settings.CacheProvider.Start(properties);1 A" W' L& H* t- z, z! I- M
#endregion, I4 q( T0 g& a! M, w9 q
# {4 W9 Z7 r1 p- s% t #region Generators ( @ W+ a- M3 }3 p identifierGenerators = new Dictionary<string, IIdentifierGenerator>();* E( q( C) Q$ r
foreach (PersistentClass model in cfg.ClassMappings) ( `# H) o8 S* y O/ Z; Y$ } {- A. |9 X e4 A B8 Q
if (!model.IsInherited)0 |& a+ f. O. Z% Q/ a7 p
{ ) c" R; l/ K" S4 Q; \6 d& t: i& {$ i IIdentifierGenerator generator = ( S+ L2 m# \) D$ [ c model.Identifier.CreateIdentifierGenerator(settings.Dialect, settings.DefaultCatalogName, # w8 r9 C3 M$ {: d( R* p4 V settings.DefaultSchemaName, (RootClass) model); $ P' j- H: n; @9 `8 b, w. N ( W4 n- H5 K) w identifierGenerators[model.EntityName] = generator; % `8 Z% F$ `9 N$ ~ S } 2 \" [, \: `1 Z; p1 O* l } / Y; N3 Z/ p/ q4 A% K' y8 [ #endregion1 |; }# r, ?0 ]
( J$ V: g0 ^3 E( L
#region Persisters ) Q: r0 d; m, @% x5 [$ Z 4 Z2 n) d g+ k# B8 s9 M Dictionary<string, ICacheConcurrencyStrategy> caches = new Dictionary<string, ICacheConcurrencyStrategy>();1 q: r# O5 D. ^( ^
entityPersisters = new Dictionary<string, IEntityPersister>(); 7 Y9 B: a |/ Q# u& ? implementorToEntityName = new Dictionary<System.Type, string>();% o, b$ T% p0 l/ c: s+ F f
: [4 o& w( R+ m2 o6 j
Dictionary<string, IClassMetadata> classMeta = new Dictionary<string, IClassMetadata>();" c% b9 X. t6 v6 O
1 C r& ]4 k: v+ N6 `$ G
foreach (PersistentClass model in cfg.ClassMappings) 0 X5 P8 D F$ k# I {' Q! H( u n, X
model.PrepareTemporaryTables(mapping, settings.Dialect);7 ]( _" w+ A1 D, H# i/ t
string cacheRegion = model.RootClazz.CacheRegionName;, T3 g$ [7 V5 H" Y% C1 K9 W
ICacheConcurrencyStrategy cache;- x3 g' s6 W; i4 X( W. N; z$ B
if (!caches.TryGetValue(cacheRegion, out cache)) : l' w3 v+ H0 ^' M7 P9 p, n* t/ n {7 {: M+ p8 g* w/ N" l! m) Q6 P
cache = 2 [- N) ]$ d- Y/ P+ v/ M CacheFactory.CreateCache(model.CacheConcurrencyStrategy, cacheRegion, model.IsMutable, settings, properties); 5 n8 S r; f5 J if (cache != null) * @( [" u4 T; O {) m$ \' c# |1 s; _, Y
caches.Add(cacheRegion, cache);8 X3 N' r" t/ ]) _ i5 u
allCacheRegions.Add(cache.RegionName, cache.Cache); & t7 P8 y$ ^( B O( M }0 n; O6 b) T3 _; h+ @
}; p8 M/ } u2 e) Z
IEntityPersister cp = PersisterFactory.CreateClassPersister(model, cache, this, mapping); ( z' a. h' m# t0 X) Z l entityPersisters[model.EntityName] = cp;5 x- e8 V6 I4 r
classMeta[model.EntityName] = cp.ClassMetadata; H f; c) h6 A7 z2 k, N4 G- Z
; K \. e1 \* k1 E, I9 _
if (model.HasPocoRepresentation)% u5 U8 U' M6 \
{ 5 V% @/ `6 ?% Z. H5 c' z implementorToEntityName[model.MappedClass] = model.EntityName;! u! ]' g, A! k
}/ L* M& G& j2 k! H8 Q( ^: \
}0 G, l! q$ r' f% a) Y
classMetadata = new UnmodifiableDictionary<string, IClassMetadata>(classMeta);1 Z, [" M; I1 i, [, b4 D9 G
1 o8 X" ^. K/ o
Dictionary<string, ISet<string>> tmpEntityToCollectionRoleMap = new Dictionary<string, ISet<string>>(); : [ {9 Z% Z0 a5 N$ |7 A3 z0 R, [ collectionPersisters = new Dictionary<string, ICollectionPersister>();$ j8 j. c7 \( Y4 V3 B: p. o# [
foreach (Mapping.Collection model in cfg.CollectionMappings)( D% J- p3 i. C3 V
{4 S- X* Z& C/ v
ICacheConcurrencyStrategy cache = 7 {; g4 A$ M% g/ m* F CacheFactory.CreateCache(model.CacheConcurrencyStrategy, model.CacheRegionName, model.Owner.IsMutable, settings, B. l+ D5 p7 X' P properties);! k' I3 t% \( V8 x
if (cache != null) % v8 A _% Z* E$ @, X {1 c G$ |5 \ q, T" f# u. q
allCacheRegions[cache.RegionName] = cache.Cache;& V. z3 i+ D7 u( O9 }; G& R
}" G9 F4 F6 d# m a4 a. m3 M& b" J
ICollectionPersister persister = PersisterFactory.CreateCollectionPersister(cfg, model, cache, this);: h6 w" l% I- x" b. o
collectionPersisters[model.Role] = persister;) ?- d {- q \# {3 F: O" T3 S2 G
IType indexType = persister.IndexType;7 M% m V# b$ h/ a
if (indexType != null && indexType.IsAssociationType && !indexType.IsAnyType) : d3 N! R/ k1 }1 } {+ ? J6 E) }. P
string entityName = ((IAssociationType) indexType).GetAssociatedEntityName(this); / C' `+ M! N: u) W0 I. K6 W7 v ISet<string> roles; ; t3 W4 x9 j$ T6 c9 ?, u if (!tmpEntityToCollectionRoleMap.TryGetValue(entityName, out roles))$ k; R _) M* o
{ . S* z4 T. T _4 \7 }( @ roles = new HashedSet<string>();+ ]1 E. ^8 ]2 y. v9 u7 {1 B+ |
tmpEntityToCollectionRoleMap[entityName] = roles; 9 N4 I# o6 t( V: K, d- v }) X/ B" v8 P5 B/ Z1 S# V# v( j1 s
roles.Add(persister.Role); & K0 J7 ]. [, P% V- t! j, G+ q/ r# c } & S- _ p& f7 P4 h% L4 z IType elementType = persister.ElementType; 1 {0 O' W, A( K2 U# W if (elementType.IsAssociationType && !elementType.IsAnyType)! }; ^ e$ x& i
{ 5 q$ V( t/ j3 t; t2 C) H% q string entityName = ((IAssociationType) elementType).GetAssociatedEntityName(this); 5 V1 i5 l3 e* ^! I ISet<string> roles; 8 i: t0 O; ?9 |+ h3 ^ if (!tmpEntityToCollectionRoleMap.TryGetValue(entityName, out roles))0 X9 {8 {8 D4 S8 e! W5 U' B; M4 q
{ % c1 S8 {8 C+ i0 u roles = new HashedSet<string>(); 5 D' }. ?6 }: M" N5 u0 W* s tmpEntityToCollectionRoleMap[entityName] = roles; " A& g5 I C+ n }: n& l; [+ Y& W, ~) M" n! R
roles.Add(persister.Role); 3 H9 t. p% L+ }" x4 y8 { z# u }5 ]! k* y1 j: I' _
}4 H" c8 [( M1 L
Dictionary<string, ICollectionMetadata> tmpcollectionMetadata = new Dictionary<string, ICollectionMetadata>(collectionPersisters.Count); 0 Q* k6 I- i4 G) a$ ^( n foreach (KeyValuePair<string, ICollectionPersister> collectionPersister in collectionPersisters): E; l4 G+ n' {+ I
{6 J3 i' \ l5 D0 L
tmpcollectionMetadata.Add(collectionPersister.Key, collectionPersister.Value.CollectionMetadata); $ V4 B8 D8 ^* Y2 S; c" E } % U1 j5 u; c( j" j collectionMetadata = new UnmodifiableDictionary<string, ICollectionMetadata>(tmpcollectionMetadata); + j/ ^5 O7 Q( B! x! ?/ v) G# t* L collectionRolesByEntityParticipant = new UnmodifiableDictionary<string, ISet<string>>(tmpEntityToCollectionRoleMap);+ I; J1 u; V* `1 C- s3 w4 ]( z' w: Y
#endregion. S& U! F, W" e0 t: T' s
% A" w4 O7 F+ [# m6 E #region Named Queries2 Y7 x* p, ?" E( A
namedQueries = new Dictionary<string, NamedQueryDefinition>(cfg.NamedQueries); 4 w. \ ]$ A' i) n! P( O$ L namedSqlQueries = new Dictionary<string, NamedSQLQueryDefinition>(cfg.NamedSQLQueries);4 p- o2 ?6 T: `% a* ~0 ?
sqlResultSetMappings = new Dictionary<string, ResultSetMappingDefinition>(cfg.SqlResultSetMappings); 8 |, K1 L5 ^7 n #endregion 9 c5 n2 F, @7 o- X- n: T ! i. y# B. R1 G) M$ s imports = new Dictionary<string, string>(cfg.Imports); / m. z# G+ u4 I2 c7 ^$ a# Y2 S* G7 z: W6 D$ H# S# Z& J
#region after *all* persisters and named queries are registered$ c/ c- ]8 g# }" S, k2 {+ ~
foreach (IEntityPersister persister in entityPersisters.Values): z3 o7 S, u+ _1 T
{# |/ `/ j, G v8 i# D% e1 U
persister.PostInstantiate(); ' V$ k/ J- s- c! d1 C }3 i6 p0 X! T: C" h8 u3 `5 ^
foreach (ICollectionPersister persister in collectionPersisters.Values) 2 T, M+ k" N/ c' Y7 w5 r% D {5 o" o" v9 o: V0 A- K
persister.PostInstantiate(); E( k4 ?( F6 W9 h6 q* ^" ]" F }. X, s3 C8 L* ?8 }
#endregion+ F, x3 m; h* J ]+ {4 F
! k1 a# L7 @" H8 e* K6 |* f
#region Serialization info 3 R6 Y! L; W- y7 E$ i, u/ f) h , }: G6 Q) o: }3 z$ M" x name = settings.SessionFactoryName; ' g$ s W9 i- z9 ~# j! @7 e try; I% c4 A7 K1 q' g$ f' b
{ & E/ @2 o7 B6 m: q4 X uuid = (string) UuidGenerator.Generate(null, null); - O- E) T u, S" c3 c9 L2 k } L/ ~! T1 ^# q( H, m: ~) h" F catch (Exception) # g9 Z' C3 W/ E8 P {) n: z" e: G' d. {* |
throw new AssertionFailure("Could not generate UUID");5 b+ \1 u3 ~3 T, d' e: w
}! e* C2 {* a( G4 Q) n
' a& A( W- x" F+ S
SessionFactoryObjectFactory.AddInstance(uuid, name, this, properties); 8 k* R+ z: R* B: g. \- |4 c4 R, [0 k& H! y5 L) S; g3 Z% ^
#endregion# q$ j$ }7 U% d( u: G
, k) N' B# o' x8 b0 k log.Debug("Instantiated session factory");) j/ ~; a' H* D2 |" }/ g2 O
! Q2 {+ c |+ M5 ?: t7 l8 b- T #region Schema management4 h E3 q6 [) i* J. j/ E
if (settings.IsAutoCreateSchema)) J. \0 U+ \% w" H; d
{" n! B7 ~4 ]1 K% ?
new SchemaExport(cfg).Create(false, true); / K' p a6 H/ L: Q8 l4 t }4 w E* Q. }5 H: h8 c( w8 O
7 P* u3 ?( A8 P! L6 R! r if ( settings.IsAutoUpdateSchema ) # V8 D7 p$ l% b/ a1 t8 y { 2 b9 n9 k; O/ I: P new SchemaUpdate(cfg).Execute(false, true);2 W4 j! S: M. Q- H4 k! [% `2 A
}3 ~4 g; A) r& v! {
if (settings.IsAutoValidateSchema)! Q7 k# N9 H# b; ]: t
{( E5 n0 u2 e. r
new SchemaValidator(cfg, settings).Validate(); y; A" \" k6 D }6 {7 A2 Z5 m) p
if (settings.IsAutoDropSchema)! J c2 Z2 ~& l V; S& g9 B7 n5 w$ f
{ / o0 d& ]* z4 U: \% K2 \ schemaExport = new SchemaExport(cfg);% o& r: Y1 Y& h m2 Y
} ' V; A" ]: Y) P2 z6 z7 F9 f #endregion7 d' `+ S! |' _% O
/ ]; y5 g2 W1 A# X* @, P- w. G #region Obtaining TransactionManager$ a& @& [8 j6 M& x$ A
// not ported yet 9 i& g% y9 @; }# h; d) U 6 ~. D& y. f* V, w! _. ?
#endregion! M; Q* H4 [/ k' u
" {& q1 q# i6 X3 P0 a& M, k currentSessionContext = BuildCurrentSessionContext(); ! V+ }& j8 Y2 m7 R9 y0 E8 y ! r8 r0 w" s& T$ G% A0 y. q if (settings.IsQueryCacheEnabled) $ M( ^, M% V {( F, i# J2 P6 y { : w) `7 x4 ?4 R" ~0 H updateTimestampsCache = new UpdateTimestampsCache(settings, properties); 2 y2 J" i( r! |- x9 D queryCache = settings.QueryCacheFactory.GetQueryCache(null, updateTimestampsCache, settings, properties);( l& O+ G% W9 P5 h$ l
queryCaches = new ThreadSafeDictionary<string, IQueryCache>(new Dictionary<string, IQueryCache>());) N" \% k- L; V: Z, L: ~' X
}+ M( ^+ a; g- g$ p/ G' P
else , Y0 S$ u H& [2 c {6 Z+ {7 u8 s9 V! X
updateTimestampsCache = null; 1 n) a0 R# I9 L queryCache = null; 7 J7 B. U" c! s3 v queryCaches = null; # E8 c) l' }( G6 B. } }7 p9 \3 D) J! [ b$ N7 \! E' J/ Y
# ?8 }! x5 q4 u; h #region Checking for named queries( F0 l4 L9 a0 l3 O& X
if (settings.IsNamedQueryStartupCheckingEnabled)8 v( j& l, ~8 N7 H
{ k0 X# ?/ w2 O7 P+ `, V, J IDictionary<string, HibernateException> errors = CheckNamedQueries(); # w J. D3 C( q, ?; ? if (errors.Count > 0); ]1 B* P! g, T. h9 ]4 R8 B' l
{2 J, n9 Z) B+ H; a' _+ V8 \
StringBuilder failingQueries = new StringBuilder("Errors in named queries: ");7 r7 ^6 E0 ~6 E+ @% N, z+ [) p
foreach (KeyValuePair<string, HibernateException> pair in errors)5 E- s! `$ ~8 d& V7 H0 F% l% T+ I o
{$ m6 m6 \( {4 ?+ p" T; b) D
failingQueries.Append('{').Append(pair.Key).Append('}'); : [. \- }2 \. |3 p! W: z" ~ log.Error("Error in named query: " + pair.Key, pair.Value);1 Q3 g+ \' P2 Y
} 5 {1 b7 Y7 S+ f* j throw new HibernateException(failingQueries.ToString()); : q: [* \) `+ W# n# \; Y9 w } ) V9 u0 i) c% f2 L } / m* Q5 j+ V C1 `0 {% Q. E: [/ K #endregion 1 @+ @( P) `7 F : _4 q% `( k4 Y0 Z6 e' @ Statistics.IsStatisticsEnabled = settings.IsStatisticsEnabled;/ k! c$ L" _6 M% S' O' i; J& ^
6 T3 g5 n3 X- s; Y7 L8 j // EntityNotFoundDelegate * K- l. Z4 n) Y& |& l" L. M l5 T IEntityNotFoundDelegate enfd = cfg.EntityNotFoundDelegate; * d4 j& N+ _. b if (enfd == null) , R* [6 C' S9 p1 Z% m) L {9 Z5 F5 V1 T- W
enfd = new DefaultEntityNotFoundDelegate(); / V: |% v3 \# o) d }2 W: d4 h! h1 I' |: m z% }" s
entityNotFoundDelegate = enfd; " c" L1 x" W# i: v& v" J+ D. ?- Y}! S: N, W5 B6 E7 U5 B& R6 s