Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions src/NHibernate.Test.VisualBasic/Issues/GH3716/Entity.vb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Namespace Issues.GH3716
Public Class Entity
Public Overridable Property Id As Guid

Public Overridable Property Date1 As Date?
End Class
End Namespace
58 changes: 58 additions & 0 deletions src/NHibernate.Test.VisualBasic/Issues/GH3716/Fixture.vb
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
Imports NHibernate.Linq
Imports NUnit.Framework

Namespace Issues.GH3716
<TestFixture>
Public Class Fixture
Inherits IssueTestCase

Protected Overrides Sub OnSetUp()

Using session As ISession = OpenSession()

Using transaction As ITransaction = session.BeginTransaction()

Dim e1 = New Entity
e1.Date1 = New Date(2017, 12, 3)
session.Save(e1)

Dim e2 = New Entity
e2.Date1 = New Date(2017, 12, 1)
session.Save(e2)

Dim e3 = New Entity
session.Save(e3)

session.Flush()
transaction.Commit()

End Using

End Using
End Sub

Protected Overrides Sub OnTearDown()

Using session As ISession = OpenSession()

Using transaction As ITransaction = session.BeginTransaction()

session.Delete("from System.Object")

session.Flush()
transaction.Commit()

End Using

End Using
End Sub

<Test>
Public Sub ShouldBeAbleToUpdateWithAnonymousType()

Using session As ISession = OpenSession()
session.Query(Of Entity).Update(Function(x) New With {.Date1 = Date.Today})
End Using
End Sub
End Class
End Namespace
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="NHibernate.Test.VisualBasic" namespace="NHibernate.Test.VisualBasic.Issues.GH3716">

<class name="Entity">
<id name="Id">
<generator class="guid.comb"/>
</id>
<property name="Date1" />
</class>

</hibernate-mapping>
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.0.0" />
<PackageReference Include="Microsoft.VisualBasic" Version="10.3.0" />
<PackageReference Include="NUnit" Version="3.14.0" />
<PackageReference Include="NUnit3TestAdapter" Version="4.6.0" />
</ItemGroup>
Expand Down
22 changes: 16 additions & 6 deletions src/NHibernate/Linq/DmlExpressionRewriter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ void AddSettersFromBindings(IEnumerable<MemberBinding> bindings, string path)
switch (node.BindingType)
{
case MemberBindingType.Assignment:
AddSettersFromAssignment((MemberAssignment)node, subPath);
AddSettersFromAssignment((MemberAssignment) node, subPath);
break;
case MemberBindingType.MemberBinding:
AddSettersFromBindings(((MemberMemberBinding)node).Bindings, subPath);
AddSettersFromBindings(((MemberMemberBinding) node).Bindings, subPath);
break;
default:
throw new InvalidOperationException($"{node.BindingType} is not supported");
Expand All @@ -53,10 +53,10 @@ void AddSettersFromAnonymousConstructor(NewExpression newExpression, string path
switch (argument.NodeType)
{
case ExpressionType.New:
AddSettersFromAnonymousConstructor((NewExpression)argument, subPath);
AddSettersFromAnonymousConstructor((NewExpression) argument, subPath);
break;
case ExpressionType.MemberInit:
AddSettersFromBindings(((MemberInitExpression)argument).Bindings, subPath);
AddSettersFromBindings(((MemberInitExpression) argument).Bindings, subPath);
break;
default:
_assignments.Add(subPath.Substring(1), Expression.Lambda(argument, _parameters));
Expand Down Expand Up @@ -121,15 +121,25 @@ public static Expression PrepareExpressionFromAnonymous<TSource>(Expression sour
if (expression == null)
throw new ArgumentNullException(nameof(expression));

// Anonymous initializations are not implemented as member initialization but as plain constructor call.
var newExpression = expression.Body as NewExpression ??
// Anonymous initializations are not implemented as member initialization but as plain constructor call, potentially wrapped in a Convert expression
var newExpression = UnwrapConvertExpression(expression.Body) as NewExpression ??
throw new ArgumentException("The expression must be an anonymous initialization, e.g. x => new { Name = x.Name, Age = x.Age + 5 }");

var instance = new DmlExpressionRewriter(expression.Parameters);
instance.AddSettersFromAnonymousConstructor(newExpression, "");
return PrepareExpression<TSource>(sourceExpression, instance._assignments);
}

private static Expression UnwrapConvertExpression(Expression expression)
{
if (expression is UnaryExpression ue && ue.NodeType == ExpressionType.Convert)
{
return ue.Operand;
}

return expression;
}

public static Expression PrepareExpression<TSource>(Expression sourceExpression, IReadOnlyDictionary<string, Expression> assignments)
{
var lambda = ConvertAssignmentsToBlockExpression<TSource>(assignments);
Expand Down
Loading