Skip to content
This repository was archived by the owner on Dec 24, 2022. It is now read-only.

Commit 5fed002

Browse files
committed
more tweaks
1 parent ebedab9 commit 5fed002

File tree

1 file changed

+41
-49
lines changed

1 file changed

+41
-49
lines changed

README.md

Lines changed: 41 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,13 @@ Effectively this allows you to create a table from any POCO type and it should p
3838

3939
_Latest v4+ on NuGet is a commercial release with [free quotas](https://servicestack.net/download#free-quotas)._
4040

41-
### [Docs and Downloads for older v3 BSD releases](https://github.com/ServiceStackV3/ServiceStackV3)
41+
#### [Docs and Downloads for older v3 BSD releases](https://github.com/ServiceStackV3/ServiceStackV3)
4242

43-
## Copying
43+
### Copying
4444

4545
Since September 2013, ServiceStack source code is available under GNU Affero General Public License/FOSS License Exception, see license.txt in the source. Alternative [commercial licensing](https://servicestack.net/ormlite) is also available.
4646

47-
## Contributing
47+
### Contributing
4848

4949
Contributors need to approve the [Contributor License Agreement](https://docs.google.com/forms/d/16Op0fmKaqYtxGL4sg7w_g-cXXyCoWjzppgkuqzOeKyk/viewform) before any code will be reviewed, see the [Contributing wiki](https://github.com/ServiceStack/ServiceStack/wiki/Contributing) for more details.
5050

@@ -343,16 +343,14 @@ To better illustrate the above query, lets expand it to the equivalent explicit
343343

344344
```csharp
345345
SqlExpression<Customer> q = db.From<Customer>();
346-
q.Join<Customer,CustomerAddress>((customer,address) => customer.Id == address.CustomerId);
346+
q.Join<Customer,CustomerAddress>((cust,address) => cust.Id == address.CustomerId);
347347

348348
List<Customer> dbCustomers = db.Select(q);
349349
```
350350

351351
### Reference Conventions
352352

353-
The above query joins together the `Customer` and `CustomerAddress` POCO's using the same relationship convention used in [OrmLite's support for References](https://github.com/ServiceStack/ServiceStack.OrmLite/blob/master/tests/ServiceStack.OrmLite.Tests/LoadReferencesTests.cs), i.e. using the referenced table `{ParentType}Id` property convention.
354-
355-
An example of what this looks like can be seen the POCO's below:
353+
The above query implicitly joins together the `Customer` and `CustomerAddress` POCO's using the same `{ParentType}Id` property convention used in [OrmLite's support for References](https://github.com/ServiceStack/ServiceStack.OrmLite/blob/master/tests/ServiceStack.OrmLite.Tests/LoadReferencesTests.cs), e.g:
356354

357355
```csharp
358356
class Customer {
@@ -381,21 +379,17 @@ class CustomerAddress {
381379
}
382380
```
383381

384-
Going back to the above example:
382+
The implicit relationship above allows you to use any of these equilvalent APIs to JOIN tables:
385383

386384
```csharp
387385
q.Join<CustomerAddress>();
388-
```
389-
390-
Uses the implicit join in the above reference convention to expand into the equivalent explicit API:
391-
392-
```csharp
393-
q.Join<Customer,CustomerAddress>((customer,address) => customer.Id == address.CustomerId);
386+
q.Join<Customer,CustomerAddress>();
387+
q.Join<Customer,CustomerAddress>((cust,address) => cust.Id == address.CustomerId);
394388
```
395389

396390
### Selecting multiple columns across joined tables
397391

398-
Another behaviour implicit when selecting from a typed SqlExpression is that results are mapped to the `Customer` POCO. To change this default we just need to explicitly specify what POCO it should map to instead:
392+
Another implicit behaviour when selecting from a typed SqlExpression is that results are mapped to the `Customer` POCO. To change this default we just need to explicitly specify what POCO it should map to instead:
399393

400394
```csharp
401395
List<FullCustomerInfo> customers = db.Select<FullCustomerInfo>(
@@ -414,40 +408,39 @@ Rules for how results are mapped is simply each property on `FullCustomerInfo` i
414408

415409
The mapping also includes a fallback for referencing fully-qualified names in the format: `{TableName}{FieldName}` allowing you to reference ambiguous fields, e.g:
416410

417-
- `CustomerId` => `Customer`.`Id`
418-
- `OrderId` => `Order`.`Id`
419-
- `CustomerName` => `Customer`.`Name`
420-
- `OrderCost` => `Order`.`Cost`
411+
- `CustomerId` => "Customer"."Id"
412+
- `OrderId` => "Order"."Id"
413+
- `CustomerName` => "Customer"."Name"
414+
- `OrderCost` => "Order"."Cost"
421415

422416
### Advanced Example
423417

424418
Seeing how the SqlExpression is constructed, joined and mapped, we can take a look at a more advanced example to showcase more of the new API's available:
425419

426420
```csharp
427-
List<FullCustomerInfo> rows = db.Select<FullCustomerInfo>( // Map results to FullCustomerInfo POCO
428-
db.From<Customer>() // Create typed Customer SqlExpression
429-
.LeftJoin<CustomerAddress>() // Implict left join with base table
430-
.Join<Customer, Order>((c,o) => c.Id == o.CustomerId) // Explicit join and condition
431-
.Where(c => c.Name == "Customer 1") // Implicit condition on base table
432-
.And<Order>(o => o.Cost < 2) // Explicit condition on joined Table
433-
.Or<Customer,Order>((c,o) => c.Name == o.LineItem)); // Explicit condition with joined Tables
421+
List<FullCustomerInfo> rows = db.Select<FullCustomerInfo>( // Map results to FullCustomerInfo POCO
422+
db.From<Customer>() // Create typed Customer SqlExpression
423+
.LeftJoin<CustomerAddress>() // Implict left join with base table
424+
.Join<Customer, Order>((c,o) => c.Id == o.CustomerId) // Explicit join and condition
425+
.Where(c => c.Name == "Customer 1") // Implicit condition on base table
426+
.And<Order>(o => o.Cost < 2) // Explicit condition on joined Table
427+
.Or<Customer,Order>((c,o) => c.Name == o.LineItem)); // Explicit condition with joined Tables
434428
```
435429

436430
The comments next to each line document each Type of API used. Some of the new API's introduced in this example include:
437431

438-
- Usage of `LeftJoin` for LEFT JOIN'S, `RightJoin` and `FullJoin` also available
439-
- Usage of `And<Table>()`, to specify a condition on a Joined table
440-
- Usage of `Or<Table1,Table2>`, to specify a condition against 2 joined tables
432+
- Usage of `LeftJoin` for specifying a LEFT JOIN, `RightJoin` and `FullJoin` also available
433+
- Usage of `And<Table>()`, to specify an **AND** condition on a Joined table
434+
- Usage of `Or<Table1,Table2>`, to specify an **OR** condition against 2 joined tables
441435

442436
More code examples of References and Joined tables are available in:
443437

444438
- [LoadReferencesTests.cs](https://github.com/ServiceStack/ServiceStack.OrmLite/blob/master/tests/ServiceStack.OrmLite.Tests/LoadReferencesTests.cs)
445439
- [LoadReferencesJoinTests.cs](https://github.com/ServiceStack/ServiceStack.OrmLite/blob/master/tests/ServiceStack.OrmLite.Tests/LoadReferencesJoinTests.cs)
446440

441+
### Reference Support, POCO style
447442

448-
### Support for references, POCO style
449-
450-
OrmLite's reference support lets Store and Load related entities with the `[Reference]` attribute, e.g:
443+
OrmLite lets you Store and Load related entities in separate tables using `[Reference]` attributes in primary tables in conjunction with `{Parent}Id` property convention in child tables, e.g:
451444

452445
```csharp
453446
public class Customer
@@ -456,18 +449,18 @@ public class Customer
456449
public int Id { get; set; }
457450
public string Name { get; set; }
458451

459-
[Reference]
452+
[Reference] // Save in CustomerAddress table
460453
public CustomerAddress PrimaryAddress { get; set; }
461454

462-
[Reference]
455+
[Reference] // Save in Order table
463456
public List<Order> Orders { get; set; }
464457
}
465458

466459
public class CustomerAddress
467460
{
468461
[AutoIncrement]
469462
public int Id { get; set; }
470-
public int CustomerId { get; set; } // `{Table}Id` convention used for parent references
463+
public int CustomerId { get; set; } // `{Parent}Id` convention to reference Customer
471464
public string AddressLine1 { get; set; }
472465
public string AddressLine2 { get; set; }
473466
public string City { get; set; }
@@ -479,14 +472,14 @@ public class Order
479472
{
480473
[AutoIncrement]
481474
public int Id { get; set; }
482-
public int CustomerId { get; set; } // `{Table}Id` convention used for parent references
475+
public int CustomerId { get; set; } // `{Parent}Id` convention to reference Customer
483476
public string LineItem { get; set; }
484477
public int Qty { get; set; }
485478
public decimal Cost { get; set; }
486479
}
487480
```
488481

489-
This lets you save a POCO and all its entity references with `db.Save()`, e.g:
482+
With the above structure you can save a POCO and all its entity references with `db.Save(T,references:true)`, e.g:
490483

491484
```csharp
492485
var customer = new Customer {
@@ -504,24 +497,23 @@ var customer = new Customer {
504497
db.Save(customer, references:true);
505498
```
506499

507-
This saves the parent customer POCO in the `Customer` table, the PrimaryAddress in the `CustomerAddress` table as well as 2 Orders in the `Order` table.
500+
This saves the root customer POCO in the `Customer` table, its related PrimaryAddress in the `CustomerAddress` table and its 2 Orders in the `Order` table.
508501

509502
More examples available in [LoadReferencesTests.cs](https://github.com/ServiceStack/ServiceStack.OrmLite/blob/master/tests/ServiceStack.OrmLite.Tests/LoadReferencesTests.cs)
510503

511504
Unlike normal complex properties, references:
512505

513-
- Doesn't persist as complex type blob
506+
- Doesn't persist as complex type blobs
514507
- Doesn't impact normal querying
515508
- Saves and loads references independently from itself
516-
- Populated references get serialized in Text serializers (only populated are visible).
517-
- Data is only loaded 1-reference-level deep
518-
- Reference Fields require consistent `(T)Id` naming
509+
- Are serializable with Text serializers (only populated are visible).
510+
- Loads related data only 1-reference-level deep
519511

520-
Basically it provides a better story when dealing with referential data that doesn't impact the POCO's ability to be used as DTO's.
512+
Basically they provides a better story when dealing with referential data that doesn't impact the POCO's ability to be used as DTO's.
521513

522514
## Optimistic Concurrency
523515

524-
Optimistic concurrency can be added to any table by adding a `ulong RowVersion { get; set; }` property, e.g:
516+
Optimistic concurrency can be added to any table by adding the `ulong RowVersion { get; set; }` property, e.g:
525517

526518
```csharp
527519
public class Poco
@@ -569,9 +561,9 @@ db.DeleteById<Poco>(id:updatedRow.Id, rowversion:updatedRow.RowVersion)
569561

570562
### Exec, Result and String Filters
571563

572-
OrmLite's core Exec functions makes it possible to inject a custom managed exec function where you can inject your own behavior, tracing, profiling, etc.
564+
OrmLite's core Exec filters makes it possible to inject your own behavior, tracing, profiling, etc.
573565

574-
It's useful in situations when you want to use SqlServer in production but use an `in-memory` Sqlite database in tests and you want to emulate any missing SQL Server Stored Procedures in code:
566+
It's useful in situations like wanting to use SqlServer in production but use an `in-memory` Sqlite database in tests and being able to emulate any missing SQL Server Stored Procedures in code:
575567

576568
```csharp
577569
public class MockStoredProcExecFilter : OrmLiteExecFilter
@@ -602,7 +594,7 @@ using (var db = OpenDbConnection())
602594
}
603595
```
604596

605-
Results filters also makes it trivial to implement the Capture filter which allows you to capture SQL Statements without running them, e.g:
597+
Results filters makes it trivial to implement the `CaptureSqlFilter` which allows you to capture SQL Statements without running them, e.g:
606598

607599
```csharp
608600
public class CaptureSqlFilter : OrmLiteResultsFilter
@@ -622,7 +614,7 @@ public class CaptureSqlFilter : OrmLiteResultsFilter
622614
}
623615
```
624616

625-
That can now wrap around existing database calls to capture, defer or print generated SQL, e.g:
617+
Which can be used to wrap around existing database calls to capture, defer or print generated SQL, e.g:
626618

627619
```csharp
628620
using (var captured = new CaptureSqlFilter())
@@ -640,7 +632,7 @@ using (var db = OpenDbConnection())
640632

641633
## Mockable extension methods
642634

643-
The Result Filters also lets you easily mock results return by OrmLite which it uses instead of hitting the database, typically useful in Unit Testing Services to mock OrmLite API's directly instead of using a repository, e.g:
635+
The Result Filters also lets you easily mock results and avoid hitting the database, typically useful in Unit Testing Services to mock OrmLite API's directly instead of using a repository, e.g:
644636

645637
```csharp
646638
using (new OrmLiteResultsFilter {

0 commit comments

Comments
 (0)