@@ -113,7 +113,7 @@ conn.Connect();
113113### 2. Register with DI
114114
115115Works in any DI host — ASP.NET Core, Worker Service, console, etc.
116- The ` AddTurquoise *` call registers the connection + UoW and returns an ` IActiveForgeBuilder ` .
116+ The provider-specific ` AddActiveForge *` call registers the connection + UoW and returns an ` IActiveForgeBuilder ` .
117117Chain ` .AddServices() ` to auto-scan your assembly for ` IService ` implementations.
118118
119119``` csharp
@@ -136,54 +136,98 @@ builder.Services
136136 .AddServices (typeof (Program ).Assembly );
137137```
138138
139- ### 3. Define an entity
139+ ### 3. Define entities
140140
141- Entity classes are provider-agnostic — the same class works with SQL Server, PostgreSQL, and MongoDB .
141+ Entity classes are provider-agnostic — the same class works with SQL Server, PostgreSQL, MongoDB, and SQLite .
142142
143143``` csharp
144144using ActiveForge ;
145145using ActiveForge .Attributes ;
146146
147- [Table (" products " )]
148- public class Product : IdentDataObject
147+ [Table (" categories " )]
148+ public class Category : IdentityRecord
149149{
150- [Column (" name" )] public TString Name = new TString ();
151- [Column (" price" )] public TDecimal Price = new TDecimal ();
152- [Column (" in_stock" )] public TBool InStock = new TBool ();
150+ [Column (" name" )] public TString Name = new TString ();
151+
152+ public Category () { }
153+ public Category (DataConnection conn ) : base (conn ) { }
154+ }
153155
154- public Product () { }
155- public Product (DataConnection conn ) : base (conn ) { }
156+ [Table (" products" )]
157+ public class Product : IdentityRecord
158+ {
159+ [Column (" name" )] public TString Name = new TString ();
160+ [Column (" price" )] public TDecimal Price = new TDecimal ();
161+ [Column (" in_stock" )]
162+ [DefaultValue (true )] public TBool InStock = new TBool ();
163+ [Column (" created_at" )]
164+ [ReadOnly ] public TDateTime CreatedAt = new TDateTime ();
165+ [Column (" notes" )]
166+ [NoPreload ] public TString Notes = new TString ();
167+ [Column (" CategoryID" )] public TForeignKey CategoryID = new TForeignKey ();
168+
169+ // Embedded Record — triggers automatic INNER JOIN in queries
170+ public Category Category ;
171+
172+ public Product () { Category = new Category (); }
173+ public Product (DataConnection conn ) : base (conn ) { Category = new Category (conn ); }
156174}
157175```
158176
159177> ** Naming conventions:** PostgreSQL folds unquoted identifiers to lower-case — use lower-case ` [Table] ` and ` [Column] ` values. MongoDB uses the attribute values as BSON field and collection names verbatim.
178+ >
179+ > ** Key attributes:** ` [ReadOnly] ` — included in SELECT but never written. ` [NoPreload] ` — excluded from the default SELECT; include via ` FieldSubset ` . ` [DefaultValue] ` — pre-populates the field on construction. ` [Sensitive] ` — masks values in diagnostic output. ` [Encrypted] ` — transparent encrypt/decrypt at ORM layer.
160180
161181### 4. CRUD
162182
163183``` csharp
164- // Insert
184+ using ActiveForge .Query ;
185+ using ActiveForge .Linq ;
186+
187+ // ── INSERT ────────────────────────────────────────────────────────────────────
165188var p = new Product (conn );
166189p .Name .SetValue (" Widget" );
167190p .Price .SetValue (9 . 99 m );
168191p .InStock .SetValue (true );
169192p .Insert (); // p.ID is populated automatically after insert
170193
171- // Read by primary key
194+ // ── READ by primary key ───────────────────────────────────────────────────────
172195var p2 = new Product (conn );
173196p2 .ID .SetValue (1 );
174- bool found = p2 .Read ();
197+ p2 .Read (); // throws PersistenceException if not found
175198
176- // Query
199+ // ── QUERY (QueryTerm API) ─────────────────────────────────────────────────────
177200var template = new Product (conn );
178201var inStock = new EqualTerm (template , template .InStock , true );
179- var results = conn .QueryAll (template , inStock , null , 0 , null );
180-
181- // Update
202+ var byName = new OrderAscending (template , template .Name );
203+ var results = conn .QueryAll (template , inStock , byName , 0 , null );
204+
205+ // ── QUERY (LINQ) ──────────────────────────────────────────────────────────────
206+ List < Product > page = conn .Query (new Product (conn ))
207+ .Where (x => x .InStock == true && x .Price < 50 m )
208+ .OrderBy (x => x .Name )
209+ .Skip (0 ).Take (20 )
210+ .ToList ();
211+
212+ // ── QUERY with JOIN filter ────────────────────────────────────────────────────
213+ List < Product > electronics = conn .Query (new Product (conn ))
214+ .Where (x => x .Category .Name == " Electronics" )
215+ .OrderBy (x => x .Price )
216+ .ToList ();
217+
218+ // ── UPDATE ────────────────────────────────────────────────────────────────────
182219p .Price .SetValue (14 . 99 m );
183- p .Update (DataObjectLock .UpdateOption .IgnoreLock );
220+ p .Update (RecordLock .UpdateOption .IgnoreLock ); // update all columns
221+
222+ p .Notes .SetValue (" On sale" );
223+ p .UpdateChanged (); // update only changed columns
224+
225+ // ── DELETE ────────────────────────────────────────────────────────────────────
226+ p .Delete (); // delete by PK
184227
185- // Delete
186- p .Delete ();
228+ // Delete by predicate:
229+ var disc = new EqualTerm (template , template .InStock , false );
230+ template .Delete (disc );
187231```
188232
189233### 5. Service proxy — automatic connection & transaction management
@@ -220,7 +264,7 @@ public class OrderService : IOrderService, IService
220264 order .ID .SetValue (orderId );
221265 _conn .Read (order );
222266 order .Status .SetValue (" Shipped" );
223- order .Update (DataObjectLock .UpdateOption .IgnoreLock );
267+ order .Update (RecordLock .UpdateOption .IgnoreLock );
224268 // commit on success; rollback + connection close on exception
225269 }
226270}
@@ -251,7 +295,7 @@ svc.Ship(42);
251295With .Transaction (uow , () =>
252296{
253297 order .Status .SetValue (" Shipped" );
254- order .Update (DataObjectLock .UpdateOption .IgnoreLock );
298+ order .Update (RecordLock .UpdateOption .IgnoreLock );
255299 shipment .Insert ();
256300});
257301```
@@ -269,7 +313,7 @@ With.Transaction(uow, () =>
269313| [ Unit of Work] ( docs/unit-of-work.md ) | ` IUnitOfWork ` , ` With.Transaction ` , Castle interceptor |
270314| [ LINQ Querying] ( docs/linq-querying.md ) | ` conn.Query<T>() ` LINQ support |
271315| [ Field Subsets] ( docs/field-subsets.md ) | Partial fetches and partial updates |
272- | [ DI & Service Proxies] ( docs/di-service-proxies.md ) | ` AddTurquoise *` , ` AddActiveForgeService<T> ` , ` [ConnectionScope] ` , ` ActiveForgeServiceFactory ` |
316+ | [ DI & Service Proxies] ( docs/di-service-proxies.md ) | ` AddActiveForge *` , ` AddActiveForgeService<T> ` , ` [ConnectionScope] ` , ` ActiveForgeServiceFactory ` |
273317| [ Advanced] ( docs/advanced.md ) | Encryption, custom mappers, polymorphism |
274318| [ ** Wiki** ] ( docs/wiki.md ) | Comprehensive reference — all concepts with examples |
275319
@@ -309,11 +353,11 @@ ActiveForge/
309353│ ├── Transactions/ ← SQLiteUnitOfWork
310354│ └── SQLiteConnection.cs
311355├── tests/
312- │ ├── ActiveForge.Tests/ ← Core library tests (314 tests)
313- │ ├── ActiveForge.SqlServer.Tests/ ← SQL Server provider tests (50 tests)
314- │ ├── ActiveForge.PostgreSQL.Tests/ ← PostgreSQL provider tests (52 tests)
315- │ ├── ActiveForge.MongoDB.Tests/ ← MongoDB provider tests (79 tests)
316- │ └── ActiveForge.SQLite.Tests/ ← SQLite provider tests (in-memory integration )
356+ │ ├── ActiveForge.Tests/ ← Core library tests (340 tests)
357+ │ ├── ActiveForge.SqlServer.Tests/ ← SQL Server provider tests (80 tests)
358+ │ ├── ActiveForge.PostgreSQL.Tests/ ← PostgreSQL provider tests (81 tests)
359+ │ ├── ActiveForge.MongoDB.Tests/ ← MongoDB provider tests (126 tests)
360+ │ └── ActiveForge.SQLite.Tests/ ← SQLite provider tests (52 tests )
317361├── examples/
318362│ └── ActiveForge.Examples/ ← Runnable console examples
319363└── docs/ ← Documentation
0 commit comments