Skip to content

Allow to assign Node.Name only once to avoid on-change subscriptions overhead #344

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 7 commits into from
Jan 16, 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
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using NUnit.Framework;
using Xtensive.Orm.Building;
using Xtensive.Orm.Building.Definitions;
using Xtensive.Orm.Model;
using Xtensive.Orm.Model.Stored;
using Xtensive.Orm.Tests.Issues.IssueJira0760_OverrideFieldNameAttributeRuinsFieldMappingOnUpgradeModel;
using Xtensive.Orm.Upgrade;
Expand Down Expand Up @@ -145,10 +147,12 @@ public void OnBuilt(Domain domain)

public void OnDefinitionsBuilt(BuildingContext context, DomainModelDef model)
{
var stateField = model.Types[typeof(EntityWithState)].Fields["State"];

stateField.Name = "EntityWithState.State";
var fields = model.Types[typeof(EntityWithState)].Fields;
var stateField = fields["State"];
fields.Remove(stateField);
typeof(Node).GetField("name", BindingFlags.Instance | BindingFlags.NonPublic).SetValue(stateField, "EntityWithState.State");
stateField.MappingName = "EntityWithState.State";
fields.Add(stateField);
}
}

Expand Down
3 changes: 1 addition & 2 deletions Orm/Xtensive.Orm/Orm/Building/Builders/IndexBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -791,8 +791,7 @@ private IEnumerable<ColumnInfo> GatherValueColumns(IEnumerable<ColumnInfo> colum
yield return column;
}
else if (!column.IsSystem) {
var clone = column.Clone();
clone.Name = nameBuilder.BuildColumnName(column);
var clone = column.Clone(nameBuilder.BuildColumnName(column));
clone.Field.MappingName = clone.Name;
_ = valueColumns.Add(clone.Name);
yield return clone;
Expand Down
3 changes: 1 addition & 2 deletions Orm/Xtensive.Orm/Orm/Building/Builders/ModelBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -373,8 +373,7 @@ private void BuildAuxiliaryTypes(IEnumerable<AssociationInfo> associations)
var underlyingType = GenerateAuxiliaryType(association);

// Defining auxiliary type
var underlyingTypeDef = modelDefBuilder.DefineType(underlyingType);
underlyingTypeDef.Name = association.Name;
var underlyingTypeDef = modelDefBuilder.DefineType(underlyingType, association.Name);
underlyingTypeDef.MappingName = context.NameBuilder.BuildAuxiliaryTypeMappingName(association);
// Copy mapping information from master type
underlyingTypeDef.MappingSchema = association.OwnerType.MappingSchema;
Expand Down
6 changes: 3 additions & 3 deletions Orm/Xtensive.Orm/Orm/Building/Builders/ModelDefBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -224,10 +224,10 @@ private void ProcessIndexes(TypeDef typeDef)

#region Definition-related members

public TypeDef DefineType(Type type)
public TypeDef DefineType(Type type, string name = null)
{
var typeDef = new TypeDef(this, type, context.Validator);
typeDef.Name = context.NameBuilder.BuildTypeName(context, typeDef);
typeDef.Name = name ?? context.NameBuilder.BuildTypeName(context, typeDef);

if (!(type.UnderlyingSystemType.IsInterface || type.IsAbstract)) {
var sta = type.GetAttribute<SystemTypeAttribute>(AttributeSearchOptions.Default);
Expand Down Expand Up @@ -382,4 +382,4 @@ public ModelDefBuilder(BuildingContext context)
types = new Queue<Type>(context.Configuration.Types);
}
}
}
}
9 changes: 4 additions & 5 deletions Orm/Xtensive.Orm/Orm/Building/Builders/TypeBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ private FieldInfo BuildDeclaredField(TypeInfo type, FieldDef fieldDef)
private void BuildInheritedField(TypeInfo type, FieldInfo inheritedField)
{
BuildLog.Info(nameof(Strings.LogBuildingInheritedFieldXY), type.Name, inheritedField.Name);
var field = inheritedField.Clone();
var field = inheritedField.Clone(null);
type.Fields.Add(field);
field.ReflectedType = type;
field.DeclaringType = inheritedField.DeclaringType;
Expand All @@ -343,15 +343,15 @@ private void BuildNestedFields(FieldInfo source, FieldInfo target, IEnumerable<F
var buffer = fields.ToList();

foreach (var field in buffer) {
var clone = field.Clone();
var newName = target.IsDeclared ? context.NameBuilder.BuildNestedFieldName(target, field) : null;
var clone = field.Clone(newName);
if (target.SkipVersion) {
clone.SkipVersion = true;
}

clone.IsSystem = false;
clone.IsLazyLoad = field.IsLazyLoad || target.IsLazyLoad;
if (target.IsDeclared) {
clone.Name = context.NameBuilder.BuildNestedFieldName(target, field);
clone.OriginalName = field.OriginalName;
// One-field reference
if (target.IsEntity && buffer.Count == 1) {
Expand Down Expand Up @@ -428,9 +428,8 @@ private ColumnInfo BuildDeclaredColumn(FieldInfo field)

private ColumnInfo BuildInheritedColumn(FieldInfo field, ColumnInfo ancestor)
{
var column = ancestor.Clone();
var column = ancestor.Clone(context.NameBuilder.BuildColumnName(field, ancestor));
column.Field = field;
column.Name = context.NameBuilder.BuildColumnName(field, ancestor);
column.IsDeclared = field.IsDeclared;
column.IsPrimaryKey = field.IsPrimaryKey;
column.IsNullable = field.IsNullable;
Expand Down
7 changes: 3 additions & 4 deletions Orm/Xtensive.Orm/Orm/Model/ColumnInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -242,15 +242,14 @@ public override bool Equals(object obj) =>
#region ICloneable methods

/// <inheritdoc/>
object ICloneable.Clone() => Clone();
object ICloneable.Clone() => Clone(null);

/// <summary>
/// Clones this instance.
/// </summary>
public ColumnInfo Clone()
public ColumnInfo Clone(string newName)
{
ColumnInfo clone = new ColumnInfo(fld);
clone.Name = Name;
ColumnInfo clone = new(fld) { Name = newName ?? Name };
clone.attributes = attributes;
clone.valueType = valueType;
clone.length = length;
Expand Down
6 changes: 3 additions & 3 deletions Orm/Xtensive.Orm/Orm/Model/FieldInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -758,15 +758,15 @@ public override int GetHashCode()
#region ICloneable methods

/// <inheritdoc/>
object ICloneable.Clone() => Clone();
object ICloneable.Clone() => Clone(null);

/// <summary>
/// Clones this instance.
/// </summary>
public FieldInfo Clone()
public FieldInfo Clone(string newName)
{
var clone = new FieldInfo(declaringType, reflectedType, Attributes) {
Name = Name,
Name = newName ?? Name,
OriginalName = OriginalName,
MappingName = MappingName,
underlyingProperty = underlyingProperty,
Expand Down
29 changes: 6 additions & 23 deletions Orm/Xtensive.Orm/Orm/Model/Node.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace Xtensive.Orm.Model
///An abstract base class for model node.
/// </summary>
[Serializable]
public abstract class Node : LockableBase, IChangeNotifier
public abstract class Node : LockableBase
{
private string name;

Expand All @@ -24,23 +24,16 @@ public abstract class Node : LockableBase, IChangeNotifier
/// </summary>
public string Name
{
get { return name; }
set {
get => name;
internal set {
EnsureNotLocked();
if (name is not null)
throw new InvalidOperationException("The node Name is locked.");
ValidateName(value);
ChangeState("Name", delegate { name = value; });
name = value;
}
}

private void ChangeState(string property, Action onChangeStateDelegate)
{
if (Changing != null)
Changing(this, new ChangeNotifierEventArgs(property));
onChangeStateDelegate();
if (Changed != null)
Changed(this, new ChangeNotifierEventArgs(property));
}

/// <summary>
/// Performs additional custom processes before setting new name to this instance.
/// </summary>
Expand All @@ -49,16 +42,6 @@ protected virtual void ValidateName(string newName)
{
}

#region IChangeNotifier Members

/// <inheritdoc/>
public event EventHandler<ChangeNotifierEventArgs> Changing;

/// <inheritdoc/>
public event EventHandler<ChangeNotifierEventArgs> Changed;

#endregion

/// <summary>
/// Updates the internal state of this instance.
/// </summary>
Expand Down
4 changes: 2 additions & 2 deletions Version.props
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

<PropertyGroup>
<DoVersion>7.2.163</DoVersion>
<DoVersionSuffix>servicetitan</DoVersionSuffix>
<DoVersion>7.2.164</DoVersion>
<DoVersionSuffix>servicetitan-test</DoVersionSuffix>
</PropertyGroup>

</Project>
Loading