Skip to content

Commit 94c97f8

Browse files
authored
Allow to assign Node.Name only once to avoid on-change subscriptions overhead (#344)
* Convert `Node.Name` into `init` setter to avoid on-change subscriptions * Clone(newName) * Fix AuxiliaryType * IssueJira0760_OverrideFieldNameAttributeRuinsFieldMappingOnUpgrade * make setter internal * Bump version
1 parent 63a2c1b commit 94c97f8

9 files changed

+30
-47
lines changed

Orm/Xtensive.Orm.Tests/Issues/IssueJira0760_OverrideFieldNameAttributeRuinsFieldMappingOnUpgrade.cs

+7-3
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@
55
using System;
66
using System.Collections.Generic;
77
using System.Linq;
8+
using System.Reflection;
89
using System.Text;
910
using NUnit.Framework;
1011
using Xtensive.Orm.Building;
1112
using Xtensive.Orm.Building.Definitions;
13+
using Xtensive.Orm.Model;
1214
using Xtensive.Orm.Model.Stored;
1315
using Xtensive.Orm.Tests.Issues.IssueJira0760_OverrideFieldNameAttributeRuinsFieldMappingOnUpgradeModel;
1416
using Xtensive.Orm.Upgrade;
@@ -145,10 +147,12 @@ public void OnBuilt(Domain domain)
145147

146148
public void OnDefinitionsBuilt(BuildingContext context, DomainModelDef model)
147149
{
148-
var stateField = model.Types[typeof(EntityWithState)].Fields["State"];
149-
150-
stateField.Name = "EntityWithState.State";
150+
var fields = model.Types[typeof(EntityWithState)].Fields;
151+
var stateField = fields["State"];
152+
fields.Remove(stateField);
153+
typeof(Node).GetField("name", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(stateField, "EntityWithState.State");
151154
stateField.MappingName = "EntityWithState.State";
155+
fields.Add(stateField);
152156
}
153157
}
154158

Orm/Xtensive.Orm/Orm/Building/Builders/IndexBuilder.cs

+1-2
Original file line numberDiff line numberDiff line change
@@ -791,8 +791,7 @@ private IEnumerable<ColumnInfo> GatherValueColumns(IEnumerable<ColumnInfo> colum
791791
yield return column;
792792
}
793793
else if (!column.IsSystem) {
794-
var clone = column.Clone();
795-
clone.Name = nameBuilder.BuildColumnName(column);
794+
var clone = column.Clone(nameBuilder.BuildColumnName(column));
796795
clone.Field.MappingName = clone.Name;
797796
_ = valueColumns.Add(clone.Name);
798797
yield return clone;

Orm/Xtensive.Orm/Orm/Building/Builders/ModelBuilder.cs

+1-2
Original file line numberDiff line numberDiff line change
@@ -373,8 +373,7 @@ private void BuildAuxiliaryTypes(IEnumerable<AssociationInfo> associations)
373373
var underlyingType = GenerateAuxiliaryType(association);
374374

375375
// Defining auxiliary type
376-
var underlyingTypeDef = modelDefBuilder.DefineType(underlyingType);
377-
underlyingTypeDef.Name = association.Name;
376+
var underlyingTypeDef = modelDefBuilder.DefineType(underlyingType, association.Name);
378377
underlyingTypeDef.MappingName = context.NameBuilder.BuildAuxiliaryTypeMappingName(association);
379378
// Copy mapping information from master type
380379
underlyingTypeDef.MappingSchema = association.OwnerType.MappingSchema;

Orm/Xtensive.Orm/Orm/Building/Builders/ModelDefBuilder.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -224,10 +224,10 @@ private void ProcessIndexes(TypeDef typeDef)
224224

225225
#region Definition-related members
226226

227-
public TypeDef DefineType(Type type)
227+
public TypeDef DefineType(Type type, string name = null)
228228
{
229229
var typeDef = new TypeDef(this, type, context.Validator);
230-
typeDef.Name = context.NameBuilder.BuildTypeName(context, typeDef);
230+
typeDef.Name = name ?? context.NameBuilder.BuildTypeName(context, typeDef);
231231

232232
if (!(type.UnderlyingSystemType.IsInterface || type.IsAbstract)) {
233233
var sta = type.GetAttribute<SystemTypeAttribute>(AttributeSearchOptions.Default);
@@ -382,4 +382,4 @@ public ModelDefBuilder(BuildingContext context)
382382
types = new Queue<Type>(context.Configuration.Types);
383383
}
384384
}
385-
}
385+
}

Orm/Xtensive.Orm/Orm/Building/Builders/TypeBuilder.cs

+4-5
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,7 @@ private FieldInfo BuildDeclaredField(TypeInfo type, FieldDef fieldDef)
325325
private void BuildInheritedField(TypeInfo type, FieldInfo inheritedField)
326326
{
327327
BuildLog.Info(nameof(Strings.LogBuildingInheritedFieldXY), type.Name, inheritedField.Name);
328-
var field = inheritedField.Clone();
328+
var field = inheritedField.Clone(null);
329329
type.Fields.Add(field);
330330
field.ReflectedType = type;
331331
field.DeclaringType = inheritedField.DeclaringType;
@@ -343,15 +343,15 @@ private void BuildNestedFields(FieldInfo source, FieldInfo target, IEnumerable<F
343343
var buffer = fields.ToList();
344344

345345
foreach (var field in buffer) {
346-
var clone = field.Clone();
346+
var newName = target.IsDeclared ? context.NameBuilder.BuildNestedFieldName(target, field) : null;
347+
var clone = field.Clone(newName);
347348
if (target.SkipVersion) {
348349
clone.SkipVersion = true;
349350
}
350351

351352
clone.IsSystem = false;
352353
clone.IsLazyLoad = field.IsLazyLoad || target.IsLazyLoad;
353354
if (target.IsDeclared) {
354-
clone.Name = context.NameBuilder.BuildNestedFieldName(target, field);
355355
clone.OriginalName = field.OriginalName;
356356
// One-field reference
357357
if (target.IsEntity && buffer.Count == 1) {
@@ -428,9 +428,8 @@ private ColumnInfo BuildDeclaredColumn(FieldInfo field)
428428

429429
private ColumnInfo BuildInheritedColumn(FieldInfo field, ColumnInfo ancestor)
430430
{
431-
var column = ancestor.Clone();
431+
var column = ancestor.Clone(context.NameBuilder.BuildColumnName(field, ancestor));
432432
column.Field = field;
433-
column.Name = context.NameBuilder.BuildColumnName(field, ancestor);
434433
column.IsDeclared = field.IsDeclared;
435434
column.IsPrimaryKey = field.IsPrimaryKey;
436435
column.IsNullable = field.IsNullable;

Orm/Xtensive.Orm/Orm/Model/ColumnInfo.cs

+3-4
Original file line numberDiff line numberDiff line change
@@ -242,15 +242,14 @@ public override bool Equals(object obj) =>
242242
#region ICloneable methods
243243

244244
/// <inheritdoc/>
245-
object ICloneable.Clone() => Clone();
245+
object ICloneable.Clone() => Clone(null);
246246

247247
/// <summary>
248248
/// Clones this instance.
249249
/// </summary>
250-
public ColumnInfo Clone()
250+
public ColumnInfo Clone(string newName)
251251
{
252-
ColumnInfo clone = new ColumnInfo(fld);
253-
clone.Name = Name;
252+
ColumnInfo clone = new(fld) { Name = newName ?? Name };
254253
clone.attributes = attributes;
255254
clone.valueType = valueType;
256255
clone.length = length;

Orm/Xtensive.Orm/Orm/Model/FieldInfo.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -758,15 +758,15 @@ public override int GetHashCode()
758758
#region ICloneable methods
759759

760760
/// <inheritdoc/>
761-
object ICloneable.Clone() => Clone();
761+
object ICloneable.Clone() => Clone(null);
762762

763763
/// <summary>
764764
/// Clones this instance.
765765
/// </summary>
766-
public FieldInfo Clone()
766+
public FieldInfo Clone(string newName)
767767
{
768768
var clone = new FieldInfo(declaringType, reflectedType, Attributes) {
769-
Name = Name,
769+
Name = newName ?? Name,
770770
OriginalName = OriginalName,
771771
MappingName = MappingName,
772772
underlyingProperty = underlyingProperty,

Orm/Xtensive.Orm/Orm/Model/Node.cs

+6-23
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ namespace Xtensive.Orm.Model
1515
///An abstract base class for model node.
1616
/// </summary>
1717
[Serializable]
18-
public abstract class Node : LockableBase, IChangeNotifier
18+
public abstract class Node : LockableBase
1919
{
2020
private string name;
2121

@@ -24,23 +24,16 @@ public abstract class Node : LockableBase, IChangeNotifier
2424
/// </summary>
2525
public string Name
2626
{
27-
get { return name; }
28-
set {
27+
get => name;
28+
internal set {
2929
EnsureNotLocked();
30+
if (name is not null)
31+
throw new InvalidOperationException("The node Name is locked.");
3032
ValidateName(value);
31-
ChangeState("Name", delegate { name = value; });
33+
name = value;
3234
}
3335
}
3436

35-
private void ChangeState(string property, Action onChangeStateDelegate)
36-
{
37-
if (Changing != null)
38-
Changing(this, new ChangeNotifierEventArgs(property));
39-
onChangeStateDelegate();
40-
if (Changed != null)
41-
Changed(this, new ChangeNotifierEventArgs(property));
42-
}
43-
4437
/// <summary>
4538
/// Performs additional custom processes before setting new name to this instance.
4639
/// </summary>
@@ -49,16 +42,6 @@ protected virtual void ValidateName(string newName)
4942
{
5043
}
5144

52-
#region IChangeNotifier Members
53-
54-
/// <inheritdoc/>
55-
public event EventHandler<ChangeNotifierEventArgs> Changing;
56-
57-
/// <inheritdoc/>
58-
public event EventHandler<ChangeNotifierEventArgs> Changed;
59-
60-
#endregion
61-
6245
/// <summary>
6346
/// Updates the internal state of this instance.
6447
/// </summary>

Version.props

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@
22
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
33

44
<PropertyGroup>
5-
<DoVersion>7.2.163</DoVersion>
6-
<DoVersionSuffix>servicetitan</DoVersionSuffix>
5+
<DoVersion>7.2.164</DoVersion>
6+
<DoVersionSuffix>servicetitan-test</DoVersionSuffix>
77
</PropertyGroup>
88

99
</Project>

0 commit comments

Comments
 (0)