You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+381Lines changed: 381 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -2,3 +2,384 @@ Shuttle.Core.Data
2
2
=================
3
3
4
4
Provides a thin abstraction over ADO.NET.
5
+
6
+
The following may be found on the [documentation site](http://shuttle.github.io/shuttle-core/overview-data/):
7
+
8
+
# Overview
9
+
10
+
The `Shuttle.Core.Data` package provides a thin abstraction over ADO.NET by making use of the `DbProviderFactories`. Even though it provides object/relational mapping mechasnims it is in no way an ORM.
11
+
12
+
# IDatabaseContextFactory
13
+
14
+
As per usual, in order to access a database, we need a database connection. A database connection is represented by a `IDatabaseContext` instance that may be obtained by using an instance of an `IDatabaseContextFactory` implementation.
15
+
16
+
The `DatabaseContextFactory` implmentation makes use of an `IDbConnectionFactory` implementation, that creates a `System.Data.IDbConnection` by using the provider name and connection string, an `IDbCommandFactory` that creates a `System.Data.IDbCommand` by using `IDbConnection` instance. The `DatabaseContextFactory` also requires an instance of a `IDatabaseContextCache` that stores connections and is assigned to the `DatabaseContext` in order to obtain the active connection.
17
+
18
+
~~~c#
19
+
varfactory=DatabaseContextFactory.Default();
20
+
21
+
using (varcontext=factory.Create("connectionStringName"))
The `DatabaseGateway` is used to execute `IQuery` instances in order return data from, or make changes to, the underlying data store. If there is no active open `IDatabaseContext` returned by the `DatabaseContext.Current` and `InvalidOperationException` will be thrown.
54
+
55
+
The following section each describe the methods available in the `IDatabaseGateway` interface.
56
+
57
+
## GetReaderUsing
58
+
59
+
~~~c#
60
+
IDataReaderGetReaderUsing(IQueryquery);
61
+
~~~
62
+
63
+
Returns an `IDataReader` instance for the given `select` statement:
64
+
65
+
~~~c#
66
+
varfactory=DatabaseContextFactory.Default();
67
+
vargateway=newDatabaseGateway();
68
+
69
+
using (varcontext=factory.Create("connectionStringName"))
70
+
{
71
+
varreader=gateway.GetReaderUsing(RawQuery.Create("select Id, Username from dbo.Member"));
72
+
}
73
+
~~~
74
+
75
+
## ExecuteUsing
76
+
77
+
~~~c#
78
+
intExecuteUsing(IQueryquery);
79
+
~~~
80
+
81
+
Executes the given query and returns the number of rows affected:
82
+
83
+
~~~c#
84
+
varfactory=DatabaseContextFactory.Default();
85
+
vargateway=newDatabaseGateway();
86
+
87
+
using (varcontext=factory.Create("connectionStringName"))
88
+
{
89
+
gateway.ExecuteUsing(RawQuery.Create("delete from dbo.Member where Username = 'mr.resistor'"));
90
+
}
91
+
~~~
92
+
93
+
## GetScalarUsing<T>
94
+
95
+
~~~c#
96
+
TGetScalarUsing<T>(IQueryquery);
97
+
~~~
98
+
99
+
Get the scalar value returned by the `select` query. The query shoud return only one value (scalar):
100
+
101
+
~~~c#
102
+
varfactory=DatabaseContextFactory.Default();
103
+
vargateway=newDatabaseGateway();
104
+
105
+
using (varcontext=factory.Create("connectionStringName"))
106
+
{
107
+
varusername=gateway.GetScalarUsing<string>(
108
+
RawQuery.Create("select Username from dbo.Member where Id = 10")
109
+
);
110
+
111
+
varid=gateway.GetScalarUsing<int>(
112
+
RawQuery.Create("select Id from dbo.Member where Username = 'mr.resistor'")
113
+
);
114
+
}
115
+
~~~
116
+
117
+
## GetDataTableFor
118
+
119
+
~~~c#
120
+
DataTableGetDataTableFor(IQueryquery);
121
+
~~~
122
+
123
+
Returns a `DataTable` containing the rows returned for the given `select` statement.
124
+
125
+
~~~c#
126
+
varfactory=DatabaseContextFactory.Default();
127
+
vargateway=newDatabaseGateway();
128
+
129
+
using (varcontext=factory.Create("connectionStringName"))
130
+
{
131
+
vartable=gateway.GetDataTableFor(RawQuery.Create("select Id, Username from dbo.Member"));
132
+
}
133
+
~~~
134
+
135
+
## GetRowsUsing
136
+
137
+
~~~c#
138
+
IEnumerable<DataRow>GetRowsUsing(IQueryquery);
139
+
~~~
140
+
141
+
Returns an enumerable containing the `DataRow` instances returned for a `select` query:
142
+
143
+
~~~c#
144
+
varfactory=DatabaseContextFactory.Default();
145
+
vargateway=newDatabaseGateway();
146
+
147
+
using (varcontext=factory.Create("connectionStringName"))
148
+
{
149
+
varrows=gateway.GetRowsUsing(RawQuery.Create("select Id, Username from dbo.Member"));
150
+
}
151
+
~~~
152
+
153
+
154
+
## GetSingleRowUsing
155
+
156
+
~~~c#
157
+
DataRowGetSingleRowUsing(IQueryquery);
158
+
~~~
159
+
160
+
Returns a single `DataRow` containing the values returned for a `select` statement that returns exactly one row:
161
+
162
+
~~~c#
163
+
varfactory=DatabaseContextFactory.Default();
164
+
vargateway=newDatabaseGateway();
165
+
166
+
using (varcontext=factory.Create("connectionStringName"))
167
+
{
168
+
varrow=gateway.GetSingleRowUsing(
169
+
RawQuery.Create("select Id, Username, EMail, DateActivated from dbo.Member where Id = 10")
170
+
);
171
+
}
172
+
~~~
173
+
174
+
# IDataRepository<T>
175
+
176
+
An `IDataRepository<T>` implementation is responsible for returning a hydrated object. To this end you make use of the `DataReposity<T>` class that takes a `IDatabaseGateway` instance along with a `IDataRowMapper<T>` used to create the hydrated instance.
177
+
178
+
The following methods can be used to interact with your object type.
179
+
180
+
## FetchAllUsing
181
+
182
+
~~~c#
183
+
IEnumerable<T>FetchAllUsing(IQueryquery);
184
+
~~~
185
+
186
+
Uses the `select` clause represented by the `IQuery` instance to create a list of objects of type `T`. The `select` clause will need to select all the required columns and will, typically, return more than one instance.
187
+
188
+
## FetchItemUsing
189
+
190
+
~~~c#
191
+
TFetchItemUsing(IQueryquery);
192
+
~~~
193
+
194
+
Returns a single object instance of type `T` that is hydrated using the data returned from the `select` clause represented by the `IQuery` instance.
This is similar to the `FetchAllUsing` method but instead returns a list of `MappedRow<T>` instances. Uses the `select` clause represented by the `IQuery` instance to create a list of `MappedRow` instances of type `T`. The `select` clause will need to select all the required columns and will, typically, return more than one instance.
203
+
204
+
## FetchMappedRowUsing
205
+
206
+
~~~c#
207
+
MappedRow<T>FetchMappedRowUsing(IQueryquery);
208
+
~~~
209
+
210
+
Similar to the `FetchItemUsing` method but instead return a `MappedRow<T>` instance that is hydrated using the data returned from the `select` clause represented by the `IQuery` instance.
211
+
212
+
## Contains
213
+
214
+
~~~c#
215
+
boolContains(IQueryquery);
216
+
~~~
217
+
218
+
Returns `true` is the `IQuery` instance `select` clause returns an `int` scalar that equals `1`; else returns `false`.
219
+
220
+
# IQuery
221
+
222
+
An `IQuery` represent a database query that can be executed against the relevant database type. There is only one method that needs to be implemented:
223
+
224
+
~~~c#
225
+
voidPrepare(IDbCommandcommand);
226
+
~~~
227
+
228
+
This should ensure that the given `IDbCommand` is configured for execution by setting the relvant command attributes and parameters.
229
+
230
+
# IQueryParameter: IQuery
231
+
232
+
An `IQueryParameter` inherits the `IQuery` interface and extends it by allowing you to add parameters to a query by specifying an `IMappedColumn` (see below) instance along with the value for the parameter.
233
+
234
+
There are two implementations of this interface.
235
+
236
+
## RawQuery
237
+
238
+
The `RawQuery` enables you to create any query using the native language structure:
239
+
240
+
~~~c#
241
+
varquery=RawQuery.Create("select UserName from dbo.Member where Id = @Id")
Typically you would not want to create a `MappedColumn` each time you need it and these are also quite fixed. A column mapping can, therefore, by defined statically:
A `MappedRow` instance contains bother a `DataRow` and the object that the `DataRow` mapped to.
331
+
332
+
This may be useful in situation where the `DataRow` contains more information that is available on the object. An example may be an `OrderLine` where the `DataRow` contains the `OrderId` column but the `OrderLine` object does not. In order to still be able to make that association it is useful to have both available.
333
+
334
+
# IAssembler
335
+
336
+
An `IAssembler` implementation is used to create multiple mappings with as few calls as possible. An example may be where we perform two `select` queries; one to get 3 orders and another to get the order lines belonging to those 3 orders.
337
+
338
+
> `select OrderId, OrderNumber, OrderDate from dbo.Order where OrderId in (2, 6, 44)`
339
+
340
+
| Order Id | Order Number | Order Date |
341
+
| --- | --- | --- |
342
+
| 2 | ORD-002 | 14 Feb 2016 |
343
+
| 6 | ORD-006 | 24 Mar 2016 |
344
+
| 44 | ORD-044 | 4 Apr 2016 |
345
+
346
+
> `select OrderId, Product, Quantity from dbo.OrderLine where OrderId in (2, 6, 44)`
347
+
348
+
| Order Id | Product | Quantity |
349
+
| --- | --- | --- |
350
+
| 2 | Red Socks | 2 |
351
+
| 2 | Blue Socks | 3 |
352
+
| 6 | Sports Towel | 1 |
353
+
| 6 | Squash Racquet | 1 |
354
+
| 6 | Squash Ball | 3 |
355
+
| 44 | Vaughn's DDD Book | 1 |
356
+
| 44 | Shuttle.Sentinel License | 5 |
357
+
358
+
Using a `MappedData` instance we can keep adding the `MappedRow` instances to the `MappedData` and then have the assembler return the three `Order` aggregates:
0 commit comments