Skip to content

NH-3944 - Upgrade Remotion.Linq to v2.1 #568

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 11, 2017
Merged

Conversation

hazzik
Copy link
Member

@hazzik hazzik commented Mar 16, 2017

  • Fix package build (release).

@fredericDelaporte
Copy link
Member

Great job, looks like it was a bit a heavy task. Probably better to merge it soon for allowing pending Linq related PR to get re-based and adapted to those incoming changes.

@fredericDelaporte
Copy link
Member

Is there any clean up you have thought of I may do?

@hazzik
Copy link
Member Author

hazzik commented Apr 5, 2017

I actually do not like all these new INh... stuff (INhQueryModelVisitor, NhHavingClause, etc). Now it looks like we are using relinq improperly.

@fredericDelaporte
Copy link
Member

fredericDelaporte commented Apr 9, 2017

I have tried to understand what is going on.

Currently, I think Relinq provides a Linq model meant to represent the Linq query, and a visitor logic to transform this model to the target (HQL tree for NHibernate).

The model supports being modified during visits. But NHibernate not only modifies it but also extends its semantic with clauses unknown from Linq (having, with, the join accepting with instead of where).

This does not look expected by Relinq designers. And doing that is harder with v2 since it has sealed a bunch of classes NHibernate was deriving from for adding and handling those additional clauses.

If we want to cease tinkering the model with additional non Linq semantic, I think we need to remove rewriters like AggregatingGroupByRewriter and handle what they were doing during the final model visit.

Maybe it is not even feasible. But it looks to me we would have easier trying to do that with current master implementation, where those additional semantics were not needing a lot of supporting code, rather than with this current migration to Relinq v2.

(And maybe there are some other issues I have not spotted currently.)

@hazzik
Copy link
Member Author

hazzik commented Apr 9, 2017

Agreed

@hazzik
Copy link
Member Author

hazzik commented May 7, 2017

@fredericDelaporte I'm going to update this PR with Expression Trees v2 Spec. At this stage, I would prefer to leave the code as close to the original as possible. It will make #594, #599 obsolete. Later if we'd think that the work in #594 is needed we can re-apply it.

There is DbOnly attribute introduced in #599. I would like it to be raised as a separate Jira. But, also, I think that it's a purpose of LinqExtensionMethodAttribute.

@fredericDelaporte
Copy link
Member

fredericDelaporte commented May 7, 2017

Ok, closing #594 and #599. I will add a Jira for DbOnly (NH-4009). Making it a purpose of LinqExtensionMethod requires to have an additional case for specifically handling MappedAs, hence my choice to have it separated, but why not.

@fredericDelaporte
Copy link
Member

DbOnly is usable on other user extensions not being a simple sql function call too. Providing it only through LinqExtensionMethod would be more limiting than having it as standalone.

We may keep it while adding an option on LinqExtensionMethod for enabling it to control that itself.

@@ -15,7 +15,7 @@ public static class EagerFetchingExtensionMethods
if (query == null) throw new ArgumentNullException(nameof(query));
if (relatedObjectSelector == null) throw new ArgumentNullException(nameof(relatedObjectSelector));

var methodInfo = ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(typeof(TOriginating), typeof(TRelated));
var methodInfo = ((MethodInfo)MethodBase.GetCurrentMethod()).MakeGenericMethod(typeof(TOriginating), typeof(TRelated));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Series of four partial conversion from space to tabs. Better convert all undue spaces of the line (or even of the file).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably rebase glitch.

{
if (visitor == null) throw new ArgumentNullException(nameof(visitor));
if (queryModel == null) throw new ArgumentNullException(nameof(queryModel));
((INhQueryModelVisitor) visitor).VisitNhHavingClause(this, queryModel, index);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Smell. I think we should open an issue on ReLinq side about their choice of restricting extensibility. Maybe will they point us toward a better of handling that, or reconsider and enable it again.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check this out: https://www.re-motion.org/jira/browse/RMLNQ-86. In short they added IBodyClause and IFromClause because of us.

if (queryModel == null) throw new ArgumentNullException(nameof(queryModel));
var nhVisitor = visitor as INhQueryModelVisitor;
if (nhVisitor == null)
throw new ArgumentException("Expect visitor to implement INhQueryModelVisitor", nameof(visitor));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better than previous but still not much satisfactory. A ReLinq owner point of view on the subject would be great.

Copy link
Member Author

@hazzik hazzik May 7, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll align all these with the same code style

{
if (visitor == null) throw new ArgumentNullException(nameof(visitor));
if (queryModel == null) throw new ArgumentNullException(nameof(queryModel));
((INhQueryModelVisitor)visitor).VisitNhWithClause(this, queryModel, index);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as previous.

NhCountExpression countExpression;
if (where != null && (countExpression = expression.QueryModel.SelectClause.Selector as NhCountExpression) !=
null && countExpression.Expression.NodeType == (ExpressionType)NhExpressionType.Star)
if (@where != null &&
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tend to remove @ "keyword escaping" prefix when it works without it.

{
// It's a join
_hqlTree.AddFromClause(
_hqlTree.TreeBuilder.Join(
HqlGeneratorExpressionTreeVisitor.Visit(fromClause.FromExpression, VisitorParameters).AsExpression(),
HqlGeneratorExpressionVisitor.Visit(fromClause.FromExpression, VisitorParameters).AsExpression(),
_hqlTree.TreeBuilder.Alias(querySourceName)));
}
else
{
// TODO - exact same code as in MainFromClause; refactor this out
Copy link
Member

@fredericDelaporte fredericDelaporte May 7, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was done here, with minimal changes. Maybe should be redone in this branch too.

expression is NhCountExpression ||
expression is NhAverageExpression ||
expression is NhMaxExpression ||
expression is NhMinExpression)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was keeping the NhNodeType for avoiding these kind of cast series, which I believe to be slower than a single cast followed by enum comparison. (And same for the new C#7 casting switch, but maybe I am wrong for him.) But I have not done any bench-marking for checking this was having a measurable impact.

I tend to not space align anything since this forbid auto-formatting (ctrl+k, ctrl+d) if we want to preserve such space alignements. Fallback on manual re-formatting instead is not a way to go for me. Tab align is not good for GitHub, so I just do not align, I simple indent (eventually putting the start on its own line if this really help reading to align).

Copy link
Member Author

@hazzik hazzik May 7, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cast should be as cheap as the equal.

The alignment was discussed with @oskarb. The consensus was that we use tabs for indents and spaces (after tabs) to align. This way it looks the same everywhere despite the size of a tab.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The default VS tooling does not support this well. As soon as we have written some code (or specifically, pasted some java code) and want to auto-fix the formatting, it switches those spaces alignements to tabs in the whole file.

Maybe I have mis-configured the tooling, but then I am unable to find the right option for preserving such formatting. (And I have tried with R# too.)

@hazzik hazzik force-pushed the NH-3944 branch 3 times, most recently from 9f18308 to 0909592 Compare May 13, 2017 12:36
@hazzik
Copy link
Member Author

hazzik commented May 15, 2017

Cleaned up, rebased, and squashed.

Copy link
Member

@fredericDelaporte fredericDelaporte left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@ngbrown ngbrown mentioned this pull request May 28, 2017
29 tasks
@ngbrown
Copy link
Contributor

ngbrown commented Jun 11, 2017

Anything holding this back from being merged?

@hazzik
Copy link
Member Author

hazzik commented Jun 11, 2017

I would like to wait until the release of "fetching"

@ngbrown
Copy link
Contributor

ngbrown commented Jun 12, 2017

@hazzik Remotion.Linq.EagerFetching v2.0.1 should be fine, because there's not actually any code changes to v2.1/2.2 just compiling for .NETStandard.

@hazzik
Copy link
Member Author

hazzik commented Jun 12, 2017 via email

@fredericDelaporte
Copy link
Member

Even with the beta 2.1 those binding redirects stays required, although it directly depends on the ReLinq 2.1 we use.

@hazzik
Copy link
Member Author

hazzik commented Jun 18, 2017

Even with the beta 2.1 those binding redirects stays required

Why is that?

@fredericDelaporte
Copy link
Member

I do not know. I have just upgraded to the beta lib, seen the bindings were still there, removed them, try testing, failure trying to load Relinq 2.0 instead of 2.1. I have not taken yet the time to enable binding failure trace and check what was going on.

@hazzik
Copy link
Member Author

hazzik commented Jun 19, 2017

Ok, there is a broken reference in the beta.

@hazzik
Copy link
Member Author

hazzik commented Jun 19, 2017

https://www.re-motion.org/jira/browse/RMLNQFETCH-21

@hazzik
Copy link
Member Author

hazzik commented Jun 26, 2017

Upgraded to re-linq 2.1.2, re-linq fetch 2.1.0. Rebased & squashed.

@fredericDelaporte please review.

Copy link
Member

@fredericDelaporte fredericDelaporte left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An unneeded dependency should be removed in main project and test project, see comment details.

Some xml comments are wrong, see comment details.

Some small additional refactoring could be done, see comment details.

C# 7 syntax could be used to reduce some new code size. But well, all that date back a bit and I would not mandate this change. What do you think about it?

</Reference>
<Reference Include="System" />
<Reference Include="System.ComponentModel.Composition" />
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This dependency looks unneeded now. Removing it, removing Remotion Nuget packages and re-adding those packages do not add it back. And tests still works without it.

<Reference Include="System" />
<Reference Include="System.ComponentModel.Composition" />
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This dependency looks unneeded now. Removing it, removing Remotion Nuget packages and re-adding those packages do not add it back. And tests still works without it.

/// <summary>
/// Accepts the specified visitor by calling its
/// <see
/// cref="M:Remotion.Linq.IQueryModelVisitor.VisitAdditionalFromClause(Remotion.Linq.Clauses.AdditionalFromClause,Remotion.Linq.QueryModel,System.Int32)" />
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Irrelevant comment. Here we call VisitNhJoinClause.

public NhJoinClause(string itemName, System.Type itemType, Expression fromExpression)
: this(itemName, itemType, fromExpression, new NhWithClause[0])
{
}

/// <summary>
/// Initializes a new instance of the <see cref="T:Remotion.Linq.Clauses.NhJoinClause" /> class.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bad namespace in the cref. The T: prefix seems to disable IDE checks.

/// uniquely identifying <see cref="T:Remotion.Linq.Clauses.IQuerySource" /> objects. To match an
/// <see cref="T:Remotion.Linq.Clauses.IQuerySource" /> with its references, use the
/// <see cref="P:Remotion.Linq.Clauses.Expressions.QuerySourceReferenceExpression.ReferencedQuerySource" /> property
/// rather than the <see cref="P:Remotion.Linq.Clauses.NhFromClauseBase.ItemName" />.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Invalid cref. But not even sure the whole remarks section is useful here.

/// Gets or sets the type of the items generated by this from clause.
/// </summary>
/// <note type="warning">
/// Changing the <see cref="P:Remotion.Linq.Clauses.NhFromClauseBase.ItemType" /> of a
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Invalid cref.

@@ -112,7 +112,7 @@ public static IEnumerable<TSource> ToFuture<TSource>(this IQueryable<TSource> so
/// <exception cref="T:System.ArgumentNullException"><paramref name="source" /> is <see langword="null"/>.</exception>
/// <exception cref="T:System.NotSupportedException"><paramref name="source" /> <see cref="IQueryable.Provider"/> is not a <see cref="INhQueryProvider"/>.</exception>
public static IFutureValue<TSource> ToFutureValue<TSource>(this IQueryable<TSource> source)
{
{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rebase glitch?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Must be

if (_type.IsAssignableFrom(joinClause.ItemType))
{
if (_querySource == null)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks as an additional change, for which I do not get the rational. Is it fixing an untested case?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was here, see L30

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, got confused by reading VisitMainFromClause instead of VisitAdditionalFromClause, sorry.

{
_joiner.MakeInnerIfJoined(memberExpression);
}
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From L100 till here, could be refactored in a method with code from L84 to L93.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll do it later

@hazzik hazzik merged commit 5cb7b3f into nhibernate:master Jul 11, 2017
@fredericDelaporte
Copy link
Member

I haven't seen you had made changes and so have not reviewed it again for having the merge "green". I you rather have an accepted review, feel free to "ping" me after changes or tell it is good enough to go without more changes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants