@@ -46,7 +46,14 @@ level public properties.
46
46
- [ ServiceStack.OrmLite.Oracle] ( http://nuget.org/packages/ServiceStack.OrmLite.Oracle ) (unofficial)
47
47
- [ ServiceStack.OrmLite.Firebird] ( http://nuget.org/List/Packages/ServiceStack.OrmLite.Firebird ) (unofficial)
48
48
- [ ServiceStack.OrmLite.VistaDb] ( http://nuget.org/List/Packages/ServiceStack.OrmLite.VistaDb ) (unofficial)
49
-
49
+
50
+ .NET Core packages:
51
+
52
+ - [ ServiceStack.OrmLite.SqlServer.Core] ( http://nuget.org/List/Packages/ServiceStack.OrmLite.SqlServer.Core )
53
+ - [ ServiceStack.OrmLite.PostgreSQL.Core] ( http://nuget.org/List/Packages/ServiceStack.OrmLite.PostgreSQL.Core )
54
+ - [ ServiceStack.OrmLite.MySql.Core] ( http://nuget.org/List/Packages/ServiceStack.OrmLite.MySql.Core )
55
+ - [ ServiceStack.OrmLite.Sqlite.Core] ( http://nuget.org/packages/ServiceStack.OrmLite.Sqlite.Core )
56
+
50
57
_ Latest v4+ on NuGet is a [ commercial release] ( https://servicestack.net/ormlite ) with [ free quotas] ( https://servicestack.net/download#free-quotas ) ._
51
58
52
59
### [ Getting Started with OrmLite and AWS RDS] ( https://github.com/ServiceStackApps/AwsGettingStarted )
@@ -451,6 +458,7 @@ db.Delete<Person>(p => p.Age == 27);
451
458
```
452
459
453
460
Or an SqlExpression:
461
+
454
462
``` csharp
455
463
var q = db .From <Person >()
456
464
.Where (p => p .Age == 27 );
@@ -463,6 +471,20 @@ As well as un-typed, string-based expressions:
463
471
db .Delete <Person >(where : " Age = @age" , new { age = 27 });
464
472
```
465
473
474
+ #### Delete from Table JOIN
475
+
476
+ Using a SqlExpression to delete rows by querying from a joined table:
477
+
478
+ ``` csharp
479
+ var q = db .From <Person >()
480
+ .Join <PersonJoin >((x , y ) => x .Id == y .PersonId )
481
+ .Where <PersonJoin >(x => x .Id == 2 );
482
+
483
+ db .Delete (q );
484
+ ```
485
+
486
+ > Not supported in MySql
487
+
466
488
# API Overview
467
489
468
490
The API is minimal, providing basic shortcuts for the primitive SQL statements:
@@ -1153,6 +1175,22 @@ SELECT "Car"."CarId", "CarType"."CarTypeName"
1153
1175
FROM " Car" INNER JOIN " CarType" WITH (READUNCOMMITTED) ON (" Car" ." CarId" = " CarType" ." CarId" )
1154
1176
```
1155
1177
1178
+ ### Custom SqlExpression Filter
1179
+
1180
+ The generated SQL from a Typed ` SqlExpression ` can also be customized using ` .WithSqlFilter() ` , e.g:
1181
+
1182
+ ``` csharp
1183
+ var q = db .From <Table >()
1184
+ .Where (x => x .Age == 27 )
1185
+ .WithSqlFilter (sql => sql + " option (recompile)" );
1186
+
1187
+ var q = db .From <Table >()
1188
+ .Where (x => x .Age == 27 )
1189
+ .WithSqlFilter (sql => sql + " WITH UPDLOCK" );
1190
+
1191
+ var results = db .Select (q );
1192
+ ```
1193
+
1156
1194
## Nested Typed Sub SqlExpressions
1157
1195
1158
1196
The ` Sql.In() ` API supports nesting and combining of multiple Typed SQL Expressions together
@@ -1532,6 +1570,19 @@ block.Area.Print(); //= 50
1532
1570
block .DateFormat .Print (); // = 2016-06-08 (SQL Server)
1533
1571
```
1534
1572
1573
+ ### Custom SQL Fragments
1574
+
1575
+ The ` Sql.Custom() ` API lets you use raw SQL Fragments in Custom ` .Select() ` expressions, e.g:
1576
+
1577
+ ``` csharp
1578
+ var q = db .From <Table >()
1579
+ .Select (x => new {
1580
+ FirstName = x .FirstName ,
1581
+ LastName = x .LastName ,
1582
+ Initials = Sql .Custom (" CONCAT(LEFT(FirstName,1), LEFT(LastName,1))" )
1583
+ });
1584
+ ```
1585
+
1535
1586
### Custom Field Declarations
1536
1587
1537
1588
The ` [CustomField] ` attribute can be used for specifying custom field declarations in the generated Create table DDL statements, e.g:
@@ -2183,27 +2234,28 @@ DEBUG: CREATE UNIQUE INDEX uidx_shippers_companyname ON "Shippers" ("CompanyName
2183
2234
```
2184
2235
2185
2236
### Transaction Support
2237
+
2186
2238
As we have direct access to IDbCommand and friends - playing with transactions is easy:
2187
2239
2188
2240
``` csharp
2189
- var trainsType = new ShipperType { Name = " Trains" };
2190
- var planesType = new ShipperType { Name = " Planes" };
2241
+ var trainsType = new ShipperType { Name = " Trains" };
2242
+ var planesType = new ShipperType { Name = " Planes" };
2191
2243
2192
- // Playing with transactions
2193
- using (IDbTransaction dbTrans = db .OpenTransaction ())
2194
- {
2195
- db .Save (trainsType );
2196
- db .Save (planesType );
2244
+ // Playing with transactions
2245
+ using (IDbTransaction dbTrans = db .OpenTransaction ())
2246
+ {
2247
+ db .Save (trainsType );
2248
+ db .Save (planesType );
2197
2249
2198
- dbTrans .Commit ();
2199
- }
2250
+ dbTrans .Commit ();
2251
+ }
2200
2252
2201
- using (IDbTransaction dbTrans = db .OpenTransaction (IsolationLevel .ReadCommitted ))
2202
- {
2203
- db .Insert (new ShipperType { Name = " Automobiles" });
2204
- Assert .That (db .Select <ShipperType >(), Has .Count .EqualTo (3 ));
2205
- }
2206
- Assert .That (db .Select <ShipperType >(), Has .Count (2 ));
2253
+ using (IDbTransaction dbTrans = db .OpenTransaction (IsolationLevel .ReadCommitted ))
2254
+ {
2255
+ db .Insert (new ShipperType { Name = " Automobiles" });
2256
+ Assert .That (db .Select <ShipperType >(), Has .Count .EqualTo (3 ));
2257
+ }
2258
+ Assert .That (db .Select <ShipperType >(), Has .Count (2 ));
2207
2259
```
2208
2260
2209
2261
### CRUD Operations
@@ -2239,27 +2291,81 @@ No ORM is complete without the standard crud operations:
2239
2291
And with access to raw sql when you need it - the database is your oyster :)
2240
2292
2241
2293
``` csharp
2242
- var partialColumns = db .Select <SubsetOfShipper >(typeof (Shipper ),
2243
- " ShipperTypeId = @Id" , new { planesType .Id });
2244
- Assert .That (partialColumns , Has .Count .EqualTo (2 ));
2294
+ var partialColumns = db .Select <SubsetOfShipper >(typeof (Shipper ),
2295
+ " ShipperTypeId = @Id" , new { planesType .Id });
2296
+ Assert .That (partialColumns , Has .Count .EqualTo (2 ));
2297
+
2298
+ // Select into another POCO class that matches sql
2299
+ var rows = db .Select <ShipperTypeCount >(
2300
+ " SELECT ShipperTypeId, COUNT(*) AS Total FROM Shippers GROUP BY ShipperTypeId ORDER BY COUNT(*)" );
2301
+
2302
+ Assert .That (rows , Has .Count .EqualTo (2 ));
2303
+ Assert .That (rows [0 ].ShipperTypeId , Is .EqualTo (trainsType .Id ));
2304
+ Assert .That (rows [0 ].Total , Is .EqualTo (1 ));
2305
+ Assert .That (rows [1 ].ShipperTypeId , Is .EqualTo (planesType .Id ));
2306
+ Assert .That (rows [1 ].Total , Is .EqualTo (2 ));
2307
+
2308
+
2309
+ // And finally lets quickly clean up the mess we've made:
2310
+ db .DeleteAll <Shipper >();
2311
+ db .DeleteAll <ShipperType >();
2312
+
2313
+ Assert .That (db .Select <Shipper >(), Has .Count .EqualTo (0 ));
2314
+ Assert .That (db .Select <ShipperType >(), Has .Count .EqualTo (0 ));
2315
+ ```
2316
+
2317
+ ## SQL Server Features
2318
+
2319
+ ### Memory Optimized Tables
2320
+
2321
+ OrmLite allows access to many advanced SQL Server features including
2322
+ [ Memory-Optimized Tables] ( https://msdn.microsoft.com/en-us/library/dn133165.aspx ) where you can tell
2323
+ SQL Server to maintain specific tables in Memory using the ` [SqlServerMemoryOptimized] ` attribute, e.g:
2324
+
2325
+ ``` csharp
2326
+ [SqlServerMemoryOptimized (SqlServerDurability .SchemaOnly )]
2327
+ public class SqlServerMemoryOptimizedCacheEntry : ICacheEntry
2328
+ {
2329
+ [PrimaryKey ]
2330
+ [StringLength (StringLengthAttribute .MaxText )]
2331
+ [SqlServerBucketCount (10000000 )]
2332
+ public string Id { get ; set ; }
2333
+ [StringLength (StringLengthAttribute .MaxText )]
2334
+ public string Data { get ; set ; }
2335
+ public DateTime CreatedDate { get ; set ; }
2336
+ public DateTime ? ExpiryDate { get ; set ; }
2337
+ public DateTime ModifiedDate { get ; set ; }
2338
+ }
2339
+ ```
2245
2340
2246
- // Select into another POCO class that matches sql
2247
- var rows = db . Select < ShipperTypeCount >(
2248
- " SELECT ShipperTypeId, COUNT(*) AS Total FROM Shippers GROUP BY ShipperTypeId ORDER BY COUNT(*) " );
2341
+ The ` [SqlServerBucketCount] ` attribute can be used to
2342
+ [ configure the bucket count for a hash index ] ( https://msdn.microsoft.com/en-us/library/mt706517.aspx#configuring_bucket_count )
2343
+ whilst the new ` [SqlServerCollate] ` attribute can be used to specify an SQL Server collation.
2249
2344
2250
- Assert .That (rows , Has .Count .EqualTo (2 ));
2251
- Assert .That (rows [0 ].ShipperTypeId , Is .EqualTo (trainsType .Id ));
2252
- Assert .That (rows [0 ].Total , Is .EqualTo (1 ));
2253
- Assert .That (rows [1 ].ShipperTypeId , Is .EqualTo (planesType .Id ));
2254
- Assert .That (rows [1 ].Total , Is .EqualTo (2 ));
2345
+ ## PostgreSQL Features
2255
2346
2347
+ ### PostgreSQL Data Types
2256
2348
2257
- // And finally lets quickly clean up the mess we've made:
2258
- db .DeleteAll <Shipper >();
2259
- db .DeleteAll <ShipperType >();
2349
+ The ` [PgSql*] ` specific attributes lets you use attributes to define PostgreSQL rich data types, e.g:
2260
2350
2261
- Assert .That (db .Select <Shipper >(), Has .Count .EqualTo (0 ));
2262
- Assert .That (db .Select <ShipperType >(), Has .Count .EqualTo (0 ));
2351
+ ``` csharp
2352
+ public class MyPostgreSqlTable
2353
+ {
2354
+ [PgSqlJson ]
2355
+ public List <Poco > AsJson { get ; set ; }
2356
+
2357
+ [PgSqlJsonB ]
2358
+ public List <Poco > AsJsonB { get ; set ; }
2359
+
2360
+ [PgSqlTextArray ]
2361
+ public string [] AsTextArray { get ; set ; }
2362
+
2363
+ [PgSqlIntArray ]
2364
+ public int [] AsIntArray { get ; set ; }
2365
+
2366
+ [PgSqlBigIntArray ]
2367
+ public long [] AsLongArray { get ; set ; }
2368
+ }
2263
2369
```
2264
2370
2265
2371
# Limitations
0 commit comments