Skip to content

Optimize FieldExpression construction #385

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
May 22, 2025
Merged
Show file tree
Hide file tree
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
30 changes: 6 additions & 24 deletions Orm/Xtensive.Orm/Orm/Linq/Expressions/EntityExpression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@
// Created by: Alexis Kochetov
// Created: 2009.05.05

using System;
using System.Linq;
using System.Collections.Generic;
using System.Linq.Expressions;
using Xtensive.Orm.Model;
using Xtensive.Orm.Linq.Expressions.Visitors;
Expand Down Expand Up @@ -184,26 +181,11 @@ public static EntityExpression Create(EntityFieldExpression entityFieldExpressio
entityFieldExpression.OuterParameter, new Dictionary<Expression, Expression>());
}

private static PersistentFieldExpression BuildNestedFieldExpression(FieldInfo nestedField, ColNum offset)
{
if (nestedField.IsPrimitive) {
return FieldExpression.CreateField(nestedField, offset);
}

if (nestedField.IsStructure) {
return StructureFieldExpression.CreateStructure(nestedField, offset);
}

if (nestedField.IsEntity) {
return EntityFieldExpression.CreateEntityField(nestedField, offset);
}

if (nestedField.IsEntitySet) {
return EntitySetExpression.CreateEntitySet(nestedField);
}

throw new NotSupportedException(string.Format(Strings.ExNestedFieldXIsNotSupported, nestedField.Attributes));
}
private static PersistentFieldExpression BuildNestedFieldExpression(FieldInfo nestedField, ColNum offset) =>
nestedField.IsStructure ? StructureFieldExpression.CreateStructure(nestedField, offset)
: nestedField.IsEntity ? EntityFieldExpression.CreateEntityField(nestedField, offset)
: nestedField.IsEntitySet ? EntitySetExpression.CreateEntitySet(nestedField)
: FieldExpression.CreateField(nestedField, offset);

public override string ToString() => $"{base.ToString()} {PersistentType.Name}";

Expand All @@ -222,4 +204,4 @@ private EntityExpression(
Key = key;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -162,10 +162,12 @@ public static EntityFieldExpression CreateEntityField(FieldInfo entityField, Col
var mapping = new Segment<ColNum>((ColNum) (mappingInfo.Offset + offset), mappingInfo.Length);
var keyFields = persistentType.Key.Fields;
var keyExpression = KeyExpression.Create(persistentType, (ColNum) (offset + mappingInfo.Offset));
var fields = new List<PersistentFieldExpression>(keyFields.Count + 1) { keyExpression };
var fields = new PersistentFieldExpression[keyFields.Count + 1];
fields[0] = keyExpression;
int i = 1;
foreach (var field in keyFields) {
// Do not convert to LINQ. We want to avoid a closure creation here.
fields.Add(BuildNestedFieldExpression(field, (ColNum) (offset + mappingInfo.Offset)));
fields[i++] = BuildNestedFieldExpression(field, (ColNum) (offset + mappingInfo.Offset));
}

return new EntityFieldExpression(persistentType, entityField, fields, mapping, keyExpression, null, null, false);
Expand Down Expand Up @@ -205,4 +207,4 @@ private EntityFieldExpression(
Entity = entity;
}
}
}
}
4 changes: 1 addition & 3 deletions Orm/Xtensive.Orm/Orm/Linq/Expressions/FieldExpression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
// Created by: Alexis Kochetov
// Created: 2009.05.05

using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using Xtensive.Core;
using Xtensive.Orm.Linq.Expressions.Visitors;
Expand Down Expand Up @@ -137,4 +135,4 @@ protected FieldExpression(
Field = field;
}
}
}
}
25 changes: 11 additions & 14 deletions Orm/Xtensive.Orm/Orm/Linq/Expressions/StructureFieldExpression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ namespace Xtensive.Orm.Linq.Expressions
internal sealed class StructureFieldExpression : FieldExpression,
IPersistentExpression
{
private List<PersistentFieldExpression> fields;
private IReadOnlyList<PersistentFieldExpression> fields;
public TypeInfo PersistentType { get; }

public bool IsNullable => Owner != null && Owner.IsNullable;

public IReadOnlyList<PersistentFieldExpression> Fields => fields;

private void SetFields(List<PersistentFieldExpression> value)
private void SetFields(IReadOnlyList<PersistentFieldExpression> value)
{
fields = value;
foreach (var fieldExpression in fields.OfType<FieldExpression>()) {
Expand Down Expand Up @@ -103,10 +103,11 @@ public override StructureFieldExpression BindParameter(ParameterExpression param

var result = new StructureFieldExpression(PersistentType, Field, Mapping, OuterParameter, DefaultIfEmpty);
processedExpressions.Add(this, result);
var processedFields = new List<PersistentFieldExpression>(fields.Count);
var processedFields = new PersistentFieldExpression[fields.Count];
int i = 0;
foreach (var field in fields) {
// Do not convert to LINQ. We want to avoid a closure creation here.
processedFields.Add((PersistentFieldExpression) field.BindParameter(parameter, processedExpressions));
processedFields[i++] = (PersistentFieldExpression) field.BindParameter(parameter, processedExpressions);
}

if (Owner == null) {
Expand All @@ -127,10 +128,11 @@ public override Expression RemoveOuterParameter(Dictionary<Expression, Expressio

var result = new StructureFieldExpression(PersistentType, Field, Mapping, OuterParameter, DefaultIfEmpty);
processedExpressions.Add(this, result);
var processedFields = new List<PersistentFieldExpression>(fields.Count);
var processedFields = new PersistentFieldExpression[fields.Count];
int i = 0;
foreach (var field in fields) {
// Do not convert to LINQ. We want to avoid a closure creation here.
processedFields.Add((PersistentFieldExpression) field.RemoveOuterParameter(processedExpressions));
processedFields[i++] = (PersistentFieldExpression) field.RemoveOuterParameter(processedExpressions);
}

if (Owner == null) {
Expand All @@ -149,14 +151,9 @@ public override FieldExpression RemoveOwner()
return this;
}

var result = new StructureFieldExpression(PersistentType, Field, Mapping, OuterParameter, DefaultIfEmpty) {
fields = new List<PersistentFieldExpression>(fields.Count)
return new StructureFieldExpression(PersistentType, Field, Mapping, OuterParameter, DefaultIfEmpty) {
fields = fields.Select(o => ((FieldExpression) o).RemoveOwner()).ToArray()
};
foreach (var field in fields) {
result.fields.Add(((FieldExpression) field).RemoveOwner());
}

return result;
}

public static StructureFieldExpression CreateStructure(FieldInfo structureField, ColNum offset)
Expand Down Expand Up @@ -213,4 +210,4 @@ private StructureFieldExpression(
PersistentType = persistentType;
}
}
}
}