Skip to content

Commit 1ee8997

Browse files
david-garcia-garciaStefH
authored andcommitted
Fixed Issue215 (#228)
* Fixes duplicate constructor issue. * fixes * xx * fixes * fix typo
1 parent c814eb2 commit 1ee8997

File tree

4 files changed

+56
-6
lines changed

4 files changed

+56
-6
lines changed

src/System.Linq.Dynamic.Core/DynamicClassFactory.cs

+4-1
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,10 @@ public static Type CreateType([NotNull] IList<DynamicProperty> properties, bool
264264
ilgeneratorToString.Emit(OpCodes.Pop);
265265
}
266266

267-
if (createParameterCtor)
267+
// Only create the default and with params constructor when there are any params.
268+
// Otherwise default constructor is not needed because it matches the default
269+
// one provided by the runtime when no constructor is present
270+
if (createParameterCtor && names.Any())
268271
{
269272
// .ctor default
270273
ConstructorBuilder constructorDef = tb.DefineConstructor(MethodAttributes.Public | MethodAttributes.HideBySig, CallingConventions.HasThis, EmptyTypes);

src/System.Linq.Dynamic.Core/Parser/ExpressionParser.cs

+6-4
Original file line numberDiff line numberDiff line change
@@ -1531,11 +1531,13 @@ Expression ParseMemberAccess(Type type, Expression instance)
15311531
return Expression.Dynamic(new DynamicGetMemberBinder(id), type, instance);
15321532
}
15331533
#endif
1534-
1535-
MethodInfo indexerMethod = instance.Type.GetMethod("get_Item", new[] { typeof(string) });
1536-
if (indexerMethod != null)
1534+
if (!_parsingConfig.DisableMemberAccessToIndexAccessorFallback)
15371535
{
1538-
return Expression.Call(instance, indexerMethod, Expression.Constant(id));
1536+
MethodInfo indexerMethod = instance.Type.GetMethod("get_Item", new[] { typeof(string) });
1537+
if (indexerMethod != null)
1538+
{
1539+
return Expression.Call(instance, indexerMethod, Expression.Constant(id));
1540+
}
15391541
}
15401542

15411543
if (_textParser.CurrentToken.Id == TokenId.Lambda && _it.Type == type)

src/System.Linq.Dynamic.Core/ParsingConfig.cs

+7
Original file line numberDiff line numberDiff line change
@@ -103,5 +103,12 @@ public IExpressionPromoter ExpressionPromoter
103103
/// Renames the (Typed)ParameterExpression empty Name to a the correct supplied name from `it`. Default value is false.
104104
/// </summary>
105105
public bool RenameParameterExpression { get; set; } = false;
106+
107+
/// <summary>
108+
/// By default when a member is not found in a type and the type has a string based index accessor it will be parsed as an index accessor. Use
109+
/// this flag to disable this behaviour and have parsing fail when parsing an expression
110+
/// where a member access on a non existing member happens. Default value is false.
111+
/// </summary>
112+
public bool DisableMemberAccessToIndexAccessorFallback { get; set; } = false;
106113
}
107114
}

test/System.Linq.Dynamic.Core.Tests/EntitiesTests.Select.cs

+39-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
using System.Collections;
2+
using System.Linq.Dynamic.Core.Exceptions;
23
using System.Linq.Dynamic.Core.Tests.Helpers.Entities;
4+
using MongoDB.Bson;
35
#if EFCORE
46
using Microsoft.EntityFrameworkCore;
57
#else
@@ -48,6 +50,42 @@ public void Entities_Select_SingleColumn()
4850
Assert.Equal<ICollection>(expected, test);
4951
}
5052

53+
[Fact]
54+
public void Entities_Select_EmptyObject()
55+
{
56+
ParsingConfig config = ParsingConfig.Default;
57+
config.EvaluateGroupByAtDatabase = true;
58+
59+
//Arrange
60+
PopulateTestData(5, 0);
61+
62+
var expected = _context.Blogs.Select(x => new {}).ToList();
63+
64+
//Act
65+
var test = _context.Blogs.GroupBy(config, "BlogId", "new()").Select<object>("new()").ToList();
66+
67+
//Assert
68+
Assert.Equal(expected.ToJson(), test.ToJson());
69+
}
70+
71+
[Fact]
72+
public void Entities_Select_BrokenObject()
73+
{
74+
ParsingConfig config = ParsingConfig.Default;
75+
config.DisableMemberAccessToIndexAccessorFallback = false;
76+
77+
// Silently creates something that will later fail on materialization
78+
var test = _context.Blogs.Select(config, "new(~.BlogId)");
79+
test = test.Select(config, "new(nonexistentproperty as howcanthiswork)");
80+
81+
// Will fail when creating the expression
82+
config.DisableMemberAccessToIndexAccessorFallback = true;
83+
Assert.ThrowsAny<ParseException>(() =>
84+
{
85+
test = test.Select(config, "new(nonexistentproperty as howcanthiswork)");
86+
});
87+
}
88+
5189
[Fact]
5290
public void Entities_Select_MultipleColumn()
5391
{
@@ -108,4 +146,4 @@ public void Entities_Select_BlogAndPosts()
108146
}
109147
}
110148
}
111-
}
149+
}

0 commit comments

Comments
 (0)