Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions Orm/Xtensive.Orm/Orm/Linq/Translator.Expressions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,9 @@
// Created by: Alexis Kochetov
// Created: 2009.02.27

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using Xtensive.Collections;
using Xtensive.Core;
using Xtensive.Linq;
using Xtensive.Orm.FullTextSearchCondition.Interfaces;
Expand Down Expand Up @@ -38,6 +34,7 @@ internal sealed partial class Translator
private static readonly Type OrmQueryableExtensionsType = typeof(QueryableExtensions);
private static readonly IReadOnlyList<ParameterExpression> ParameterContextParams = [Expression.Parameter(WellKnownOrmTypes.ParameterContext, "context")];
private static readonly ParameterExpression ParameterContextParam = Expression.Parameter(WellKnownOrmTypes.ParameterContext, "context");
private static readonly ConcurrentDictionary<(Type Type, MemberInfo MemberInfo), PropertyInfo> memberCache = new();
Copy link

Choose a reason for hiding this comment

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

It looks like it could be kinda big in ST context. Could you measure actual cost of sourceExpression.Type.GetProperty(memberInfo.Name, memberInfo.GetBindingFlags())? Reflection has caches, maybe it's cheap.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It will be big, but all Type, MemberInfo, PropertyInfo are reused
so we allocate this memory anyway. Just don't want to spend time on reflection logic


private static readonly ConstantExpression
NullExpression = Expression.Constant(null),
Expand Down Expand Up @@ -345,11 +342,15 @@ protected override Expression VisitMember(MemberExpression ma)
var sourceExpression = ma.Expression;

if (sourceExpression != null) {
if (sourceExpression.Type != memberInfo.ReflectedType
var sourceExpressionType = sourceExpression.Type;
var memberInfoReflectedType = memberInfo.ReflectedType;
if (sourceExpressionType != memberInfoReflectedType
&& memberInfo is PropertyInfo
&& !memberInfo.ReflectedType.IsInterface) {
&& !memberInfoReflectedType.IsInterface) {
ma = Expression.MakeMemberAccess(
sourceExpression, sourceExpression.Type.GetProperty(memberInfo.Name, memberInfo.GetBindingFlags()));
sourceExpression,
memberCache.GetOrAdd((sourceExpressionType, memberInfo),
static t => t.Type.GetProperty(t.MemberInfo.Name, t.MemberInfo.GetBindingFlags())));

memberInfo = ma.Member;
sourceExpression = ma.Expression;
Expand Down