Skip to content

Commit 590dd55

Browse files
committed
Automatically cast from SimpleQuery to collections and such where possible (issue ThatRendle#219)
1 parent e1556ca commit 590dd55

6 files changed

Lines changed: 143 additions & 3 deletions

File tree

ProfilingApp/CastTask.cs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Diagnostics;
4+
using System.Linq;
5+
using Simple.Data;
6+
7+
namespace ProfilingApp
8+
{
9+
public class CastTask : IProfileTask
10+
{
11+
private readonly dynamic _db = Database.OpenConnection(Properties.Settings.Default.ConnectionString);
12+
13+
public void Run()
14+
{
15+
var watch = Stopwatch.StartNew();
16+
17+
List<Post> posts = _db.Posts.All().ToList<Post>();
18+
Console.WriteLine(posts.Count);
19+
watch.Stop();
20+
Console.WriteLine(watch.Elapsed);
21+
}
22+
}
23+
24+
public class Post
25+
{
26+
public int ID { get; set; }
27+
public string Title { get; set; }
28+
public string Content { get; set; }
29+
public DateTime Created { get; set; }
30+
}
31+
}

ProfilingApp/ProfilingApp.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
<Reference Include="System.Xml" />
4444
</ItemGroup>
4545
<ItemGroup>
46+
<Compile Include="CastTask.cs" />
4647
<Compile Include="FindAllByTask.cs" />
4748
<Compile Include="FindByTask.cs" />
4849
<Compile Include="IProfileTask.cs" />

ProfilingApp/Program.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ class Program
1212
{
1313
static void Main(string[] args)
1414
{
15-
ResetDatabase();
15+
//ResetDatabase();
1616

17-
new FindByTask().Run();
17+
new CastTask().Run();
1818
}
1919

2020
private static void ResetDatabase()

ProfilingApp/Resources/DatabaseResetSql.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ DECLARE @PostId AS INT
3131
DECLARE @PostIdStr AS NVARCHAR(3)
3232
DECLARE @Loop AS INT
3333
SET @PostId = 1
34-
WHILE @PostId <= 100
34+
WHILE @PostId <= 2500
3535
BEGIN
3636
SET @PostIdStr = CAST(@PostId AS NVARCHAR(3))
3737
INSERT INTO [dbo].[Post] ([Id], [Title], [Content], [Created]) VALUES (@PostId, 'Post ' + @PostIdStr, 'This is post number ' + @PostIdStr, GETDATE())
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
using System.Collections.Generic;
2+
using System.Collections.ObjectModel;
3+
using System.Linq;
4+
using NUnit.Framework;
5+
6+
namespace Simple.Data.InMemoryTest
7+
{
8+
[TestFixture]
9+
public class SimpleQueryConversionTests
10+
{
11+
[Test]
12+
public void ShouldCastToList()
13+
{
14+
Database.UseMockAdapter(new InMemoryAdapter());
15+
var db = Database.Open();
16+
db.Test.Insert(Id: 1, Name: "Alice");
17+
db.Test.Insert(Id: 2, Name: "Bob");
18+
List<Person> records = db.Test.All();
19+
Assert.IsNotNull(records);
20+
Assert.AreEqual(2, records.Count);
21+
}
22+
23+
[Test]
24+
public void ShouldCastToPersonCollection()
25+
{
26+
Database.UseMockAdapter(new InMemoryAdapter());
27+
var db = Database.Open();
28+
db.Test.Insert(Id: 1, Name: "Alice");
29+
db.Test.Insert(Id: 2, Name: "Bob");
30+
PersonCollection records = db.Test.All();
31+
Assert.IsNotNull(records);
32+
Assert.AreEqual(2, records.Count);
33+
}
34+
35+
[Test]
36+
public void ShouldCastToIEnumerableOfPerson()
37+
{
38+
Database.UseMockAdapter(new InMemoryAdapter());
39+
var db = Database.Open();
40+
db.Test.Insert(Id: 1, Name: "Alice");
41+
db.Test.Insert(Id: 2, Name: "Bob");
42+
IEnumerable<Person> records = db.Test.All();
43+
Assert.IsNotNull(records);
44+
Assert.AreEqual(2, records.Count());
45+
}
46+
}
47+
48+
public class Person
49+
{
50+
public int Id { get; set; }
51+
public string Name { get; set; }
52+
}
53+
54+
public class PersonCollection : Collection<Person>
55+
{
56+
57+
}
58+
}

Simple.Data/SimpleQuery.cs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,9 +106,59 @@ public override bool TryConvert(ConvertBinder binder, out object result)
106106
result = Cast<dynamic>();
107107
return true;
108108
}
109+
110+
var collectionType = binder.Type.GetInterface("ICollection`1");
111+
if (collectionType != null)
112+
{
113+
if (TryConvertToGenericCollection(binder, out result, collectionType)) return true;
114+
}
115+
116+
if (binder.Type.Name.Equals("IEnumerable`1"))
117+
{
118+
var genericArguments = binder.Type.GetGenericArguments();
119+
var cast =
120+
typeof (SimpleQuery).GetMethod("Cast").MakeGenericMethod(genericArguments);
121+
result = cast.Invoke(this, null);
122+
return true;
123+
}
124+
109125
return base.TryConvert(binder, out result);
110126
}
111127

128+
private bool TryConvertToGenericCollection(ConvertBinder binder, out object result, Type collectionType)
129+
{
130+
var genericArguments = collectionType.GetGenericArguments();
131+
var enumerableConstructor =
132+
binder.Type.GetConstructor(new[]
133+
{
134+
typeof (IEnumerable<>).MakeGenericType(
135+
genericArguments)
136+
});
137+
if (enumerableConstructor != null)
138+
{
139+
var cast =
140+
typeof (SimpleQuery).GetMethod("Cast").MakeGenericMethod(genericArguments);
141+
result = Activator.CreateInstance(binder.Type, cast.Invoke(this, null));
142+
return true;
143+
}
144+
145+
var defaultConstructor = binder.Type.GetConstructor(new Type[0]);
146+
if (defaultConstructor != null)
147+
{
148+
result = Activator.CreateInstance(binder.Type);
149+
var add = binder.Type.GetMethod("Add", genericArguments);
150+
var cast =
151+
typeof (SimpleQuery).GetMethod("Cast").MakeGenericMethod(genericArguments);
152+
foreach (var item in (IEnumerable) cast.Invoke(this, null))
153+
{
154+
add.Invoke(result, new[] {item});
155+
}
156+
return true;
157+
}
158+
result = null;
159+
return false;
160+
}
161+
112162
/// <summary>
113163
/// Selects only the specified columns.
114164
/// </summary>

0 commit comments

Comments
 (0)