Skip to content

Commit 2bff2b7

Browse files
committed
1 parent dfcb4ab commit 2bff2b7

22 files changed

+165
-4863
lines changed
-155 KB
Binary file not shown.

.vs/DynamicLinqWithEfCoreTest/v15/Server/sqlite3/db.lock

Whitespace-only changes.
Binary file not shown.
Binary file not shown.
Binary file not shown.

DynamicLinqWithEfCoreTest/DynamicLinqWithEfCoreTest.csproj

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
1-
<Project Sdk="Microsoft.NET.Sdk">
1+
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
44
<OutputType>Exe</OutputType>
55
<TargetFramework>netcoreapp2.0</TargetFramework>
66
</PropertyGroup>
77

88
<ItemGroup>
9-
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="2.0.2" />
9+
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.1.0-rc1-final" />
1010
</ItemGroup>
1111

1212
<ItemGroup>

DynamicLinqWithEfCoreTest/Program.cs

+163-99
Original file line numberDiff line numberDiff line change
@@ -1,99 +1,163 @@
1-
using Microsoft.EntityFrameworkCore;
2-
using System;
3-
using System.Collections.Generic;
4-
using System.Diagnostics;
5-
using System.Linq;
6-
using System.Linq.Dynamic.Core;
7-
8-
namespace DynamicLinqWithEfCoreTest
9-
{
10-
class Program
11-
{
12-
static void Main(string[] args)
13-
{
14-
var list = new List<Person>
15-
{
16-
new Person
17-
{
18-
Age = 1,
19-
EnglishName = "sadfasdf",
20-
Id = Guid.NewGuid(),
21-
Name = "tom"
22-
},
23-
new Person
24-
{
25-
Age = 2,
26-
EnglishName = "ddddd",
27-
Id = Guid.NewGuid(),
28-
Name = "jerry"
29-
}
30-
};
31-
32-
using (var context = new TestContext())
33-
{
34-
context.Set<Person>().AddRange(list);
35-
context.SaveChanges();
36-
}
37-
38-
const int num = 100_000;
39-
40-
var sw = Stopwatch.StartNew();
41-
42-
for (var i = 0; i < num; i++)
43-
{
44-
using (var context = new TestContext())
45-
{
46-
var set = context.Set<Person>().Where(m => m.Age == 1 && m.Name == "tom").ToList();
47-
}
48-
}
49-
50-
Console.WriteLine(sw.Elapsed);
51-
52-
sw.Restart();
53-
54-
for (var i = 0; i < num; i++)
55-
{
56-
using (var context = new TestContext())
57-
{
58-
var set = context.Set<Person>().Where("$.Age==@0 and $.Name==@1", 1, "tom").ToList();
59-
}
60-
}
61-
62-
Console.WriteLine(sw.Elapsed);
63-
64-
//Console.WriteLine("Press any key to quit");
65-
//Console.ReadKey();
66-
}
67-
}
68-
69-
public class Person
70-
{
71-
public Guid Id { get; set; }
72-
public int Age { get; set; }
73-
public string Name { get; set; }
74-
public string EnglishName { get; set; }
75-
}
76-
77-
public class TestContext : DbContext
78-
{
79-
public TestContext()
80-
{
81-
82-
}
83-
84-
public TestContext(DbContextOptions<TestContext> options) : base(options)
85-
{
86-
87-
}
88-
89-
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
90-
{
91-
optionsBuilder.UseInMemoryDatabase("test");
92-
}
93-
94-
protected override void OnModelCreating(ModelBuilder modelBuilder)
95-
{
96-
modelBuilder.Entity<Person>().HasKey(m => m.Id);
97-
}
98-
}
99-
}
1+
using Microsoft.EntityFrameworkCore;
2+
using Microsoft.EntityFrameworkCore.Diagnostics;
3+
using Microsoft.Extensions.Logging;
4+
using System;
5+
using System.Collections.Generic;
6+
using System.Diagnostics;
7+
using System.Linq;
8+
using System.Linq.Dynamic.Core;
9+
using System.Linq.Expressions;
10+
11+
namespace DynamicLinqWithEfCoreTest
12+
{
13+
class Program
14+
{
15+
static void Main(string[] args)
16+
{
17+
var list = new List<Person>
18+
{
19+
new Person
20+
{
21+
Age = 1,
22+
EnglishName = "sadfasdf",
23+
Id = Guid.NewGuid(),
24+
Name = "tom"
25+
},
26+
new Person
27+
{
28+
Age = 2,
29+
EnglishName = "ddddd",
30+
Id = Guid.NewGuid(),
31+
Name = "jerry"
32+
}
33+
};
34+
35+
using (var context = new TestContext())
36+
{
37+
try
38+
{
39+
//DynamicExpressionParser.ParseLambda(new ParsingConfig { UseDynamicObjectClassForAnonymousTypes = true }, null, "new {1 AS Id}");
40+
41+
context.Database.EnsureCreated();
42+
43+
context.Set<Person>().AddRange(list);
44+
context.SaveChanges();
45+
46+
context.Set<Person>().Select(d => new Tuple<int>(d.Age)).GroupBy(d => new Tuple<int>(d.Item1)).Select("new {Key.Item1, Sum(Item1) As Value}").TryLogToList("exp: Tuple,Tuple");
47+
context.Set<Person>().Select(d => new { Id = d.Age }).GroupBy(d => new { Id = d.Id }).Select("new {Key.Id, Sum(Id) As Value}").TryLogToList("exp: Anonymous,Anonymous");
48+
context.Set<Person>().Select(d => new { Id = d.Age }).GroupBy(d => new Tmp1 { Id = d.Id }).Select("new {Key.Id, Sum(Id) As Value}").TryLogToList("exp: Anonymous,Tmp1; should failed");
49+
context.Set<Person>().Select(d => new { Id = d.Age }).GroupBy(d => new Tmp2 { Id = d.Id }).Select("new {Key.Id, Sum(Id) As Value}").TryLogToList("exp: Anonymous,Tmp2; should failed");
50+
context.Set<Person>().Select(d => new Tmp1 { Id = d.Age }).GroupBy(d => new { Id = d.Id }).Select("new {Key.Id, Sum(Id) As Value}").TryLogToList("exp: Tmp1,Anonymous; should failed");
51+
context.Set<Person>().Select(d => new Tmp2 { Id = d.Age }).GroupBy(d => new { Id = d.Id }).Select("new {Key.Id, Sum(Id) As Value}").TryLogToList("exp: Tmp2,Anonymous; should failed");
52+
53+
context.Set<Person>().Select("new { Age AS Id }").GroupBy("new { Id }").Select("new {Key.Id, Sum(Id) As Value}").TryLogToList("dyn: Anonymous,Anonymous");
54+
//Note the changed in #117 for Anonymous Type is also needed
55+
context.Set<Person>().Select4Test("new { Age AS Id }", true).GroupBy4Test("new { Id }", true).Select("new {Key.Id, Sum(Id) As Value}").TryLogToList("dyn: Anonymous,Anonymous; with createParameterCtor=true");
56+
context.Set<Person>().Select4Test("new { Age AS Id }", false).GroupBy4Test("new { Id }", false).Select("new {Key.Id, Sum(Id) As Value}").TryLogToList("dyn: Anonymous,Anonymous; with createParameterCtor=false");
57+
58+
context.Set<Person>().Select<Tmp1>("new { Age AS Id }").GroupBy(DynamicExpressionParser.ParseLambda<Tmp1, Tmp1>(null, false, "new { Id }")).Select("new {Key.Id, Sum(Id) As Value}").TryLogToList("dyn: Tmp1,Tmp1(without ParameterCtor)");
59+
context.Set<Person>().Select<Tmp2>("new { Age AS Id }").GroupBy(DynamicExpressionParser.ParseLambda<Tmp2, Tmp2>(null, false, "new { Id }")).Select("new {Key.Id, Sum(Id) As Value}").TryLogToList("dyn: Tmp2,Tmp2(with ParameterCtor)");
60+
}
61+
finally
62+
{
63+
context.Database.EnsureDeleted();
64+
}
65+
}
66+
67+
Console.WriteLine("Press any key to quit");
68+
Console.ReadKey();
69+
}
70+
//one class without createParameterCtor
71+
public class Tmp1
72+
{
73+
public Tmp1()
74+
{
75+
}
76+
public int Id { get; set; }
77+
}
78+
//one class with createParameterCtor
79+
public class Tmp2
80+
{
81+
public Tmp2()
82+
{
83+
}
84+
public Tmp2(int id)
85+
{
86+
}
87+
public int Id { get; set; }
88+
}
89+
}
90+
91+
internal static class TestUtils
92+
{
93+
public static IQueryable Select4Test(this IQueryable source, string selector, bool createParameterCtor)
94+
{
95+
LambdaExpression lambda = DynamicExpressionParser.ParseLambda(null, createParameterCtor, source.ElementType, null, selector);
96+
97+
var optimized = Expression.Call(
98+
typeof(Queryable), nameof(Queryable.Select),
99+
new[] { source.ElementType, lambda.Body.Type },
100+
source.Expression, Expression.Quote(lambda));
101+
102+
return source.Provider.CreateQuery(optimized);
103+
}
104+
105+
public static IQueryable GroupBy4Test(this IQueryable source, string keySelector, bool createParameterCtor)
106+
{
107+
var keyLambda = DynamicExpressionParser.ParseLambda(null, createParameterCtor, source.ElementType, null, keySelector);
108+
109+
var optimized = Expression.Call(
110+
typeof(Queryable), nameof(Queryable.GroupBy),
111+
new[] { source.ElementType, keyLambda.Body.Type }, source.Expression, Expression.Quote(keyLambda));
112+
113+
return source.Provider.CreateQuery(optimized);
114+
}
115+
116+
public static List<dynamic> TryLogToList(this IQueryable queryable, string tag)
117+
{
118+
try
119+
{
120+
var res = queryable.ToDynamicList();
121+
Console.Error.WriteLine($"Success query with {tag}." + Environment.NewLine);
122+
return res;
123+
}
124+
catch (Exception e)
125+
{
126+
Console.Error.WriteLine($"Failed query with {tag}:" + Environment.NewLine + e.Message + Environment.NewLine);
127+
return null;
128+
}
129+
}
130+
}
131+
132+
public class Person
133+
{
134+
public Guid Id { get; set; }
135+
public int Age { get; set; }
136+
public string Name { get; set; }
137+
public string EnglishName { get; set; }
138+
}
139+
140+
public class TestContext : DbContext
141+
{
142+
public TestContext()
143+
{
144+
145+
}
146+
147+
public TestContext(DbContextOptions<TestContext> options) : base(options)
148+
{
149+
150+
}
151+
152+
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
153+
{
154+
optionsBuilder.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=Test165;Trusted_Connection=True;")
155+
.ConfigureWarnings(warns=>warns.Throw(RelationalEventId.QueryClientEvaluationWarning));
156+
}
157+
158+
protected override void OnModelCreating(ModelBuilder modelBuilder)
159+
{
160+
modelBuilder.Entity<Person>().HasKey(m => m.Id);
161+
}
162+
}
163+
}

0 commit comments

Comments
 (0)