Skip to content

Commit 9a7ca30

Browse files
committed
ORM
1 parent d94288b commit 9a7ca30

File tree

5 files changed

+97
-83
lines changed

5 files changed

+97
-83
lines changed

.vs/DataCommander.sqlite

0 Bytes
Binary file not shown.

DataCommander.Providers/ResultWriter/LogResultWriter.cs

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -78,11 +78,14 @@ void IResultWriter.AfterCloseReader(int affectedRows)
7878
void IResultWriter.WriteTableBegin(DataTable schemaTable)
7979
{
8080
_writeTableBeginTimestamp = Stopwatch.GetTimestamp();
81-
var columns = schemaTable.Rows.Cast<DataRow>().Select(i => new DbColumn(i)).ToList();
8281

82+
var objectId = _tableCount + 1;
83+
var objectTypeName = $"Object{objectId}";
84+
var objectInstanceName = "@object";
85+
var columns = schemaTable.Rows.Cast<DataRow>().Select(i => new DbColumn(i)).ToList();
8386
var stringBuilder = new StringBuilder();
84-
stringBuilder.Append("\r\ninternal sealed class Row");
85-
stringBuilder.Append(_tableCount);
87+
stringBuilder.Append("\r\ninternal sealed class ");
88+
stringBuilder.Append(objectTypeName);
8689
stringBuilder.Append("\r\n{\r\n");
8790

8891
var first = true;
@@ -104,13 +107,13 @@ void IResultWriter.WriteTableBegin(DataTable schemaTable)
104107
stringBuilder.Append(";");
105108
}
106109

107-
stringBuilder.Append("\r\n}\r\nprivate static Row");
108-
stringBuilder.Append(_tableCount);
109-
stringBuilder.Append(" Read");
110-
stringBuilder.Append(_tableCount);
111-
stringBuilder.Append("(IDataRecord dataRecord)\r\n{\r\n var row = new Row");
112-
stringBuilder.Append(_tableCount);
113-
stringBuilder.Append("();\r\n");
110+
stringBuilder.AppendFormat(@"
111+
}}
112+
113+
private static {0} Read{0}(IDataRecord dataRecord)
114+
{{
115+
var {1} = new {0}();
116+
", objectTypeName, objectInstanceName);
114117

115118
first = true;
116119
var index = 0;
@@ -121,7 +124,7 @@ void IResultWriter.WriteTableBegin(DataTable schemaTable)
121124
else
122125
stringBuilder.AppendLine();
123126

124-
stringBuilder.Append(" row.");
127+
stringBuilder.AppendFormat(" {0}.",objectInstanceName);
125128
stringBuilder.Append(column.ColumnName);
126129
stringBuilder.Append(" = dataRecord.");
127130
stringBuilder.Append(GetDataRecordMethodName(column));
@@ -132,7 +135,10 @@ void IResultWriter.WriteTableBegin(DataTable schemaTable)
132135
++index;
133136
}
134137

135-
stringBuilder.Append("\r\n return row;\r\n}\r\n");
138+
stringBuilder.AppendFormat(@"
139+
return {0};
140+
}}
141+
", objectInstanceName);
136142

137143
Log.Trace($"SchemaTable of table[{_tableCount}]:\r\n{schemaTable.ToStringTableString()}\r\n{stringBuilder}");
138144

Foundation/Data/DbDataReaderExtensions.cs

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,19 @@ public static async Task ReadAsync(this DbDataReader dataReader, Action read, Ca
1616
read();
1717
}
1818

19-
public static async Task ReadAsync(this DbDataReader dataReader, IEnumerable<Action> reads, CancellationToken cancellationToken)
19+
public static async Task ReadAsync(this DbDataReader dataReader, IEnumerable<Func<Task>> reads, CancellationToken cancellationToken)
2020
{
21+
var first = true;
2122
foreach (var read in reads)
2223
{
23-
await dataReader.ReadAsync(read, cancellationToken);
24-
var nextResult = await dataReader.NextResultAsync(cancellationToken);
25-
FoundationContract.Assert(nextResult);
24+
if (first)
25+
first = false;
26+
else
27+
{
28+
var nextResult = await dataReader.NextResultAsync(cancellationToken);
29+
FoundationContract.Assert(nextResult);
30+
}
31+
await read();
2632
}
2733
}
2834

@@ -48,13 +54,13 @@ public static async Task<ExecuteReaderResponse<T1, T2>> ReadAsync<T1, T2>(
4854
List<T1> objects1 = null;
4955
List<T2> objects2 = null;
5056

51-
var reads = new Action[]
57+
var readResults = new Func<Task>[]
5258
{
5359
async () => objects1 = await dataReader.ReadAsync(read1, cancellationToken),
5460
async () => objects2 = await dataReader.ReadAsync(read2, cancellationToken),
5561
};
5662

57-
await dataReader.ReadAsync(reads, cancellationToken);
63+
await dataReader.ReadAsync(readResults, cancellationToken);
5864

5965
return ExecuteReaderResponse.Create(objects1, objects2);
6066
}
@@ -70,7 +76,7 @@ public static async Task<ExecuteReaderResponse<T1, T2, T3>> ReadAsync<T1, T2, T3
7076
List<T2> objects2 = null;
7177
List<T3> objects3 = null;
7278

73-
var reads = new Action[]
79+
var reads = new Func<Task>[]
7480
{
7581
async () => objects1 = (await dataReader.ReadAsync(read1, cancellationToken)),
7682
async () => objects2 = (await dataReader.ReadAsync(read2, cancellationToken)),

Foundation/Data/IDbCommandAsyncExecutorExtensions.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,8 @@ public static async Task ExecuteAsync(this IDbCommandAsyncExecutor executor, IEn
1515
await executor.ExecuteAsync(async connection =>
1616
{
1717
foreach (var request in requests)
18-
{
1918
using (var command = connection.CreateCommand(request.CreateCommandRequest))
2019
await request.Execute(command);
21-
}
2220
}, cancellationToken);
2321
}
2422

README.md

Lines changed: 66 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -26,87 +26,91 @@ Result: sort in memory|Yes|No
2626

2727
## [Object-relational mapping (ORM)](https://en.wikipedia.org/wiki/Object-relational_mapping)
2828

29-
1. Download and restore the SQL Server 2016 sample database from https://github.com/microsoft/sql-server-samples
30-
2. Open the database with Data Commander and execute the following command:
29+
Download and restore the SQL Server 2016 sample database from https://github.com/microsoft/sql-server-samples
3130

32-
```SQL
33-
use WideWorldImporters
34-
35-
select top 0
36-
CustomerID,
37-
CustomerName,
38-
BillToCustomerID,
39-
CustomerCategoryID
40-
from Sales.Customers
31+
Open the database with Data Commander and execute the following command:
4132

42-
select top 0 *
43-
from Sales.CustomerTransactions
33+
```SQL
34+
select
35+
c.CustomerID,
36+
c.CustomerName
37+
from Sales.Customers c
38+
39+
select
40+
i.InvoiceID,
41+
i.CustomerID,
42+
i.InvoiceDate
43+
from Sales.Invoices i
44+
order by i.CustomerID,i.InvoiceID
4445
```
4546

46-
3. The program generates C# ORM code snippets. See them in the Messages window:
47+
The program generates C# ORM code snippets. See them in log file:
4748

4849
```C#
49-
internal sealed class Row0
50+
internal sealed class Customer
5051
{
51-
public int CustomerID;
52-
public string CustomerName;
53-
public int BillToCustomerID;
54-
public int CustomerCategoryID;
52+
public int CustomerID;
53+
public string CustomerName;
5554
}
5655

57-
private static Row0 Read0(IDataRecord dataRecord)
56+
private static Customer ReadCustomer(IDataRecord dataRecord)
5857
{
59-
var row = new Row0();
60-
row.CustomerID = dataRecord.GetInt32(0);
61-
row.CustomerName = dataRecord.GetString(1);
62-
row.BillToCustomerID = dataRecord.GetInt32(2);
63-
row.CustomerCategoryID = dataRecord.GetInt32(3);
64-
return row;
58+
var @object = new Customer();
59+
@object.CustomerID = dataRecord.GetInt32(0);
60+
@object.CustomerName = dataRecord.GetString(1);
61+
return @object;
6562
}
6663

67-
internal sealed class Row1
64+
internal sealed class Invoice
6865
{
69-
public int CustomerTransactionID;
70-
public int CustomerID;
71-
public int TransactionTypeID;
72-
public int? InvoiceID;
73-
public int? PaymentMethodID;
74-
public DateTime TransactionDate;
75-
public decimal AmountExcludingTax;
76-
public decimal TaxAmount;
77-
public decimal TransactionAmount;
78-
public decimal OutstandingBalance;
79-
public DateTime? FinalizationDate;
80-
public bool? IsFinalized;
81-
public int LastEditedBy;
82-
public DateTime LastEditedWhen;
66+
public int InvoiceID;
67+
public int CustomerID;
68+
public DateTime InvoiceDate;
8369
}
8470

85-
private static Row1 Read1(IDataRecord dataRecord)
71+
private static Invoice ReadInvoice(IDataRecord dataRecord)
8672
{
87-
var row = new Row1();
88-
row.CustomerTransactionID = dataRecord.GetInt32(0);
89-
row.CustomerID = dataRecord.GetInt32(1);
90-
row.TransactionTypeID = dataRecord.GetInt32(2);
91-
row.InvoiceID = dataRecord.GetNullableInt32(3);
92-
row.PaymentMethodID = dataRecord.GetNullableInt32(4);
93-
row.TransactionDate = dataRecord.GetDateTime(5);
94-
row.AmountExcludingTax = dataRecord.GetDecimal(6);
95-
row.TaxAmount = dataRecord.GetDecimal(7);
96-
row.TransactionAmount = dataRecord.GetDecimal(8);
97-
row.OutstandingBalance = dataRecord.GetDecimal(9);
98-
row.FinalizationDate = dataRecord.GetNullableDateTime(10);
99-
row.IsFinalized = dataRecord.GetNullableBoolean(11);
100-
row.LastEditedBy = dataRecord.GetInt32(12);
101-
row.LastEditedWhen = dataRecord.GetDateTime(13);
102-
return row;
73+
var @object = new Invoice();
74+
@object.InvoiceID = dataRecord.GetInt32(0);
75+
@object.CustomerID = dataRecord.GetInt32(1);
76+
@object.InvoiceDate = dataRecord.GetDateTime(2);
77+
return @object;
10378
}
79+
```
80+
81+
2. The generated code can be used like this:
82+
83+
```C#
84+
var connectionStringBuilder = new SqlConnectionStringBuilder();
85+
connectionStringBuilder.DataSource = @".\SQL2016_001";
86+
connectionStringBuilder.InitialCatalog = "WideWorldImporters";
87+
connectionStringBuilder.IntegratedSecurity = true;
10488

105-
private static ExecuteReaderResponse<Row0,Row1> Execute(this IDbCommandExecutor executor)
89+
using (var connection = new SqlConnection(connectionStringBuilder.ConnectionString))
10690
{
107-
const string commandText = "...";
108-
var request = new ExecuteReaderRequest(commandText);
109-
return executor.Read(request,Read0,Read1);
91+
connection.Open();
92+
var executor = connection.CreateCommandAsyncExecutor();
93+
94+
var commandText = "waitfor delay '00:00:01'";
95+
var affectedRows = await executor.ExecuteNonQueryAsync(new ExecuteNonReaderRequest(commandText));
96+
97+
commandText = "select top 1 i.InvoiceID from Sales.Invoices i";
98+
var scalar = await executor.ExecuteScalarAsync(new ExecuteNonReaderRequest(commandText));
99+
100+
var commandText = @"select
101+
c.CustomerID,
102+
c.CustomerName
103+
from Sales.Customers c
104+
105+
select
106+
i.InvoiceID,
107+
i.CustomerID,
108+
i.InvoiceDate
109+
from Sales.Invoices i
110+
order by i.CustomerID,i.InvoiceID";
111+
var response = await executor.ExecuteReaderAsync(new ExecuteReaderRequest(commandText), ReadCustomer, ReadInvoice);
112+
var customers = response.Objects1;
113+
var invoices = response.Objects2;
110114
}
111115

112116
```

0 commit comments

Comments
 (0)