diff --git a/src/NHibernate.Test/NHibernate.Test.csproj b/src/NHibernate.Test/NHibernate.Test.csproj
index 11cc9888c37..18ff7ce1300 100644
--- a/src/NHibernate.Test/NHibernate.Test.csproj
+++ b/src/NHibernate.Test/NHibernate.Test.csproj
@@ -65,6 +65,8 @@
+
+
diff --git a/src/NHibernate.Test/RawBenchSessionManagerPerfomance.cs b/src/NHibernate.Test/RawBenchSessionManagerPerfomance.cs
new file mode 100644
index 00000000000..12a6dc8ee4f
--- /dev/null
+++ b/src/NHibernate.Test/RawBenchSessionManagerPerfomance.cs
@@ -0,0 +1,110 @@
+//#define UPSTREAM
+using System;
+using System.IO;
+using NHibernate.Util;
+using NUnit.Framework;
+
+
+namespace NHibernate.Test
+{
+ [TestFixture]
+ public class RawBenchSessionManagerPerfomance
+ {
+#if UPSTREAM
+ [Test]
+ public void InternLevel_Upstream()
+ {
+ //Just to force initialize static ctor and do not calculate memory consumed by Environoment
+ Cfg.Environment.VerifyProperties(CollectionHelper.EmptyDictionary());
+
+ RunTest();
+ }
+
+#else
+
+ [Test]
+ public void InternLevel_Minimal()
+ {
+ Cfg.Environment.InternLevel = InternLevel.Minimal;
+ RunTest();
+ }
+
+ [Test]
+ public void InternLevel_Default()
+ {
+ Cfg.Environment.InternLevel = InternLevel.Default;
+ RunTest();
+ }
+
+ [Test]
+ public void InternLevel_SessionFactories()
+ {
+ Cfg.Environment.InternLevel = InternLevel.SessionFactories;
+ RunTest();
+ }
+
+ [Test]
+ public void InternLevel_AppDomains()
+ {
+ Cfg.Environment.InternLevel = InternLevel.AppDomains;
+ RunTest();
+ }
+
+
+#endif
+
+ private static void RunTest()
+ {
+ var factory = NH.Bencher.SessionManager.SessionFactory;
+
+ var setup = new AppDomainSetup();
+ var si = AppDomain.CurrentDomain.SetupInformation;
+ setup.ApplicationBase = si.ApplicationBase;
+ setup.ConfigurationFile = si.ConfigurationFile;
+
+ AppDomain newDomain = AppDomain.CreateDomain("New Domain", null, si);
+
+#if !UPSTREAM
+ newDomain.SetData("internLevel", Cfg.Environment.InternLevel);
+#endif
+ try
+ {
+ newDomain.DoCallBack(
+ () =>
+ {
+ StringWriter s = new StringWriter();
+ Console.SetOut(s);
+ Console.WriteLine();
+ Console.WriteLine();
+ Console.WriteLine("From new App Domain...");
+#if !UPSTREAM
+ Cfg.Environment.InternLevel = (InternLevel) AppDomain.CurrentDomain.GetData("internLevel");
+#endif
+ try
+ {
+
+ var factory2 = NH.Bencher.SessionManager.SessionFactory;
+ }
+ finally
+ {
+ AppDomain.CurrentDomain.SetData("log", s.ToString());
+ AppDomain.CurrentDomain.SetData("memory", NH.Bencher.SessionManager.LastTotalMemoryUsage);
+ }
+ });
+ }
+ finally
+ {
+ Console.WriteLine(newDomain.GetData("log"));
+ Console.WriteLine("Total Memory Usage in 2 App Domains: " + ToKbSize((long) newDomain.GetData("memory") + NH.Bencher.SessionManager.LastTotalMemoryUsage));
+
+ AppDomain.Unload(newDomain);
+ }
+ }
+
+ private static string ToKbSize(long bytes)
+ {
+ return (bytes / 1024.0).ToString("0,0.00") + " Kb";
+ }
+ }
+
+}
diff --git a/src/NHibernate.sln b/src/NHibernate.sln
index d50878b114d..069eea00733 100644
--- a/src/NHibernate.sln
+++ b/src/NHibernate.sln
@@ -1,6 +1,6 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
-VisualStudioVersion = 15.0.26730.12
+VisualStudioVersion = 15.0.27130.2003
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{593DCEA7-C933-46F3-939F-D8172399AB05}"
ProjectSection(SolutionItems) = preProject
@@ -21,6 +21,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "NHibernate.TestDatabaseSetu
EndProject
Project("{778DAE3C-4631-46EA-AA77-85C1314464D9}") = "NHibernate.Test.VisualBasic", "NHibernate.Test.VisualBasic\NHibernate.Test.VisualBasic.vbproj", "{7C2EF610-BCA0-4D1F-898A-DE9908E4970C}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NH.Bencher.Model", "RawBencher\Model\NH.Bencher.Model.csproj", "{45DAEB56-B84D-4D7A-BF22-293F1CE07DBB}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "NH.Bencher.Persistence", "RawBencher\Persistence\NH.Bencher.Persistence.csproj", "{3E9CA88C-03EC-445A-960A-242511B6EF55}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -47,6 +51,14 @@ Global
{7C2EF610-BCA0-4D1F-898A-DE9908E4970C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7C2EF610-BCA0-4D1F-898A-DE9908E4970C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7C2EF610-BCA0-4D1F-898A-DE9908E4970C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {45DAEB56-B84D-4D7A-BF22-293F1CE07DBB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {45DAEB56-B84D-4D7A-BF22-293F1CE07DBB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {45DAEB56-B84D-4D7A-BF22-293F1CE07DBB}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {45DAEB56-B84D-4D7A-BF22-293F1CE07DBB}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3E9CA88C-03EC-445A-960A-242511B6EF55}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3E9CA88C-03EC-445A-960A-242511B6EF55}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3E9CA88C-03EC-445A-960A-242511B6EF55}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3E9CA88C-03EC-445A-960A-242511B6EF55}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/src/NHibernate/Cfg/Environment.cs b/src/NHibernate/Cfg/Environment.cs
index ce55bead051..d444134dfe5 100644
--- a/src/NHibernate/Cfg/Environment.cs
+++ b/src/NHibernate/Cfg/Environment.cs
@@ -270,12 +270,15 @@ public static string Version
///
public const string TrackSessionId = "track_session_id";
+ public const string StringMetadataInternLevel = "intern_level";
+
private static readonly Dictionary GlobalProperties;
private static IBytecodeProvider BytecodeProviderInstance;
private static bool EnableReflectionOptimizer;
-
+
private static readonly INHibernateLogger log = NHibernateLogger.For(typeof(Environment));
+ private static InternLevel _internLevel;
///
/// Issue warnings to user when any obsolete property names are used.
@@ -299,6 +302,9 @@ static Environment()
BytecodeProviderInstance = BuildBytecodeProvider(GlobalProperties);
EnableReflectionOptimizer = PropertiesHelper.GetBoolean(PropertyUseReflectionOptimizer, GlobalProperties);
+
+ //TODO: Proper configuration
+ SetInternLevelFromConfig();
if (EnableReflectionOptimizer)
{
@@ -306,6 +312,27 @@ static Environment()
}
}
+ //TODO:
+ private static InternLevel SetInternLevelFromConfig()
+ {
+ return InternLevel.Default;
+ //string value = System.Configuration.ConfigurationManager.AppSettings["InternLevel"];
+ //Console.WriteLine("Path to config file: " + ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None).FilePath);
+
+ //if (string.IsNullOrEmpty(value))
+ //{
+ // return InternLevel.Default;
+ //}
+
+ //if (!Enum.TryParse(value, true, out var valueParsed))
+ //{
+ // Console.WriteLine("Intern level setting is invalid: " + value);
+ //}
+ //Console.WriteLine("Intern level " + valueParsed);
+ //Console.WriteLine();
+ //return valueParsed;
+ }
+
private static void LoadGlobalPropertiesFromAppConfig()
{
object config = ConfigurationManager.GetSection(CfgXmlHelper.CfgSectionName);
@@ -388,6 +415,32 @@ public static IBytecodeProvider BytecodeProvider
set { BytecodeProviderInstance = value; }
}
+ ///
+ /// The bytecode provider to use.
+ ///
+ ///
+ /// This property is read from the <nhibernate> section
+ /// of the application configuration file by default. Since it is not
+ /// always convenient to configure NHibernate through the application
+ /// configuration file, it is also possible to set the property value
+ /// manually. This should only be done before a configuration object
+ /// is created, otherwise the change may not take effect.
+ ///
+ public static InternLevel InternLevel
+ {
+ get { return _internLevel; }
+ set
+ {
+
+ if (value != _internLevel)
+ {
+ Console.WriteLine("Intern level " + value);
+ }
+ _internLevel = value;
+
+ }
+ }
+
///
/// Whether to enable the use of reflection optimizer
///
diff --git a/src/NHibernate/Dialect/Lock/SelectLockingStrategy.cs b/src/NHibernate/Dialect/Lock/SelectLockingStrategy.cs
index ed696ce67b9..faf9d990b61 100644
--- a/src/NHibernate/Dialect/Lock/SelectLockingStrategy.cs
+++ b/src/NHibernate/Dialect/Lock/SelectLockingStrategy.cs
@@ -47,7 +47,7 @@ private SqlString GenerateLockString()
{
select.SetComment(lockMode + " lock " + lockable.EntityName);
}
- return select.ToSqlString();
+ return select.ToSqlString(true);
}
#region ILockingStrategy Members
@@ -110,4 +110,4 @@ public void Lock(object id, object version, object obj, ISessionImplementor sess
#endregion
}
-}
\ No newline at end of file
+}
diff --git a/src/NHibernate/Loader/BasicLoader.cs b/src/NHibernate/Loader/BasicLoader.cs
index 1e2055329cc..5d9aaa49d70 100644
--- a/src/NHibernate/Loader/BasicLoader.cs
+++ b/src/NHibernate/Loader/BasicLoader.cs
@@ -13,7 +13,7 @@ public abstract class BasicLoader : Loader
private IEntityAliases[] descriptors;
private ICollectionAliases[] collectionDescriptors;
- public BasicLoader(ISessionFactoryImplementor factory) : base(factory) {}
+ public BasicLoader(ISessionFactoryImplementor factory) : base(factory) { }
protected override sealed IEntityAliases[] EntityAliases
{
@@ -28,6 +28,8 @@ protected override sealed ICollectionAliases[] CollectionAliases
protected abstract string[] Suffixes { get; }
protected abstract string[] CollectionSuffixes { get; }
+ protected virtual bool InternStringMetadata => false;
+
protected override void PostInstantiate()
{
ILoadable[] persisters = EntityPersisters;
@@ -35,7 +37,7 @@ protected override void PostInstantiate()
descriptors = new IEntityAliases[persisters.Length];
for (int i = 0; i < descriptors.Length; i++)
{
- descriptors[i] = new DefaultEntityAliases(persisters[i], suffixes[i]);
+ descriptors[i] = new DefaultEntityAliases(persisters[i], suffixes[i], InternStringMetadata);
}
ICollectionPersister[] collectionPersisters = CollectionPersisters;
@@ -69,7 +71,7 @@ protected override void PostInstantiate()
private static bool IsBag(ICollectionPersister collectionPersister)
{
var type = collectionPersister.CollectionType.GetType();
- return type.IsGenericType && type.GetGenericTypeDefinition() == typeof (GenericBagType<>);
+ return type.IsGenericType && type.GetGenericTypeDefinition() == typeof(GenericBagType<>);
}
///
diff --git a/src/NHibernate/Loader/DefaultEntityAliases.cs b/src/NHibernate/Loader/DefaultEntityAliases.cs
index 8ff8a43e65f..fb74056f446 100644
--- a/src/NHibernate/Loader/DefaultEntityAliases.cs
+++ b/src/NHibernate/Loader/DefaultEntityAliases.cs
@@ -1,5 +1,6 @@
using System.Collections.Generic;
using NHibernate.Persister.Entity;
+using NHibernate.Util;
namespace NHibernate.Loader
{
@@ -34,6 +35,34 @@ public DefaultEntityAliases(IDictionary userProvidedAliases, I
//rowIdAlias is generated on demand in property
}
+ ///
+ /// Calculate and cache select-clause aliases.
+ ///
+ public DefaultEntityAliases(ILoadable persister, string suffix, bool internAliases) : this(persister, suffix)
+ {
+ if (internAliases == false)
+ return;
+
+ const InternLevel internLevel = InternLevel.EntityAlias;
+
+ SuffixedKeyAliases = StringHelper.Intern(SuffixedKeyAliases, internLevel);
+ SuffixedPropertyAliases = InternPropertiesAliases(SuffixedPropertyAliases, internLevel);
+ SuffixedVersionAliases = StringHelper.Intern(SuffixedVersionAliases, internLevel);
+ SuffixedDiscriminatorAlias = StringHelper.Intern(SuffixedDiscriminatorAlias, internLevel);
+ if (persister.HasRowId)
+ RowIdAlias = StringHelper.Intern(RowIdAlias, internLevel);
+ }
+
+ private string[][] InternPropertiesAliases(string[][] propertiesAliases, InternLevel internLevel)
+ {
+ foreach (string[] values in propertiesAliases)
+ {
+ StringHelper.Intern(values, internLevel);
+ }
+
+ return propertiesAliases;
+ }
+
///
/// Returns aliases for subclass persister
///
@@ -63,7 +92,11 @@ public string[][] GetSuffixedPropertyAliases(ILoadable persister)
public string[] SuffixedKeyAliases { get; }
// TODO: not visible to the user!
- public string RowIdAlias => _rowIdAlias ?? (_rowIdAlias = Loadable.RowIdAlias + _suffix);
+ public string RowIdAlias
+ {
+ get => _rowIdAlias ?? (_rowIdAlias = Loadable.RowIdAlias + _suffix);
+ private set => _rowIdAlias = value;
+ }
///
/// Returns default aliases for all the properties
@@ -100,7 +133,7 @@ private string[] DetermineKeyAliases(ILoadable persister)
if (_userProvidedAliases != null)
{
var result = SafeGetUserProvidedAliases(persister.IdentifierPropertyName) ??
- GetUserProvidedAliases(EntityPersister.EntityID);
+ GetUserProvidedAliases(EntityPersister.EntityID);
if (result != null)
return result;
@@ -108,24 +141,24 @@ private string[] DetermineKeyAliases(ILoadable persister)
return GetIdentifierAliases(persister, _suffix);
}
-
+
private string[][] DeterminePropertyAliases(ILoadable persister)
{
return GetSuffixedPropertyAliases(persister);
}
-
+
private string DetermineDiscriminatorAlias(ILoadable persister)
{
if (_userProvidedAliases != null)
{
var columns = GetUserProvidedAliases(AbstractEntityPersister.EntityClass);
- if (columns != null)
+ if (columns != null)
return columns[0];
}
return GetDiscriminatorAlias(persister, _suffix);
}
-
+
private string[] SafeGetUserProvidedAliases(string propertyPath)
{
if (propertyPath == null)
diff --git a/src/NHibernate/Loader/Entity/CascadeEntityLoader.cs b/src/NHibernate/Loader/Entity/CascadeEntityLoader.cs
index a30bf394100..856efa406fd 100644
--- a/src/NHibernate/Loader/Entity/CascadeEntityLoader.cs
+++ b/src/NHibernate/Loader/Entity/CascadeEntityLoader.cs
@@ -16,5 +16,7 @@ public CascadeEntityLoader(IOuterJoinLoadable persister, CascadingAction action,
log.Debug("Static select for action {0} on entity {1}: {2}", action, entityName, SqlString);
}
+
+ protected override bool InternStringMetadata => true;
}
}
diff --git a/src/NHibernate/Loader/Entity/EntityLoader.cs b/src/NHibernate/Loader/Entity/EntityLoader.cs
index af222d4e894..80bafc6d653 100644
--- a/src/NHibernate/Loader/Entity/EntityLoader.cs
+++ b/src/NHibernate/Loader/Entity/EntityLoader.cs
@@ -48,5 +48,7 @@ protected override bool IsSingleRowLoader
{
get { return !batchLoader; }
}
+
+ protected override bool InternStringMetadata => true;
}
}
diff --git a/src/NHibernate/Mapping/Collection.cs b/src/NHibernate/Mapping/Collection.cs
index 49677325626..34e325345b7 100644
--- a/src/NHibernate/Mapping/Collection.cs
+++ b/src/NHibernate/Mapping/Collection.cs
@@ -176,7 +176,7 @@ public bool IsLazy
public string Role
{
get { return role; }
- set { role = StringHelper.InternedIfPossible(value); }
+ set { role = StringHelper.Intern(value, InternLevel.CollectionRole); }
}
public IEnumerable ColumnIterator
diff --git a/src/NHibernate/Mapping/Column.cs b/src/NHibernate/Mapping/Column.cs
index d807125c547..cc5f65f6ed1 100644
--- a/src/NHibernate/Mapping/Column.cs
+++ b/src/NHibernate/Mapping/Column.cs
@@ -1,4 +1,5 @@
using System;
+using System.Text;
using NHibernate.Dialect.Function;
using NHibernate.Engine;
using NHibernate.SqlTypes;
@@ -13,6 +14,8 @@ namespace NHibernate.Mapping
[Serializable]
public class Column : ISelectable, ICloneable
{
+ private const char QuoteChar = '`';
+
public const int DefaultLength = 255;
public const int DefaultPrecision = 19;
public const int DefaultScale = 2;
@@ -82,18 +85,21 @@ public string Name
get { return _name; }
set
{
- if (value[0] == '`')
- {
- _quoted = true;
- _name = value.Substring(1, value.Length - 2);
- }
- else
- {
- _name = value;
- }
+ _name = StringHelper.Intern(GetName(value, out _quoted), InternLevel.ColumnName);
}
}
+ private string GetName(string value, out bool quoted)
+ {
+ quoted = false;
+ if (value[0] == QuoteChar)
+ {
+ quoted = true;
+ return value.Substring(1, value.Length - 2);
+ }
+ return value;
+ }
+
public string CanonicalName
{
get { return _quoted ? _name : _name.ToLowerInvariant(); }
@@ -154,8 +160,9 @@ private string GetAlias(int maxAliasLength)
// those checks, then the double checks for total length can be reduced to one.
// But I will leave it like this for now to make it look similar. /Oskar 2016-08-20
bool useRawName = name.Length + suffix.Length <= usableLength &&
- !_quoted &&
- !StringHelper.EqualsCaseInsensitive(name, "rowid");
+ !_quoted &&
+ !string.Equals(name, "rowid", StringComparison.OrdinalIgnoreCase);
+
if (!useRawName)
{
if (suffix.Length >= usableLength)
@@ -428,7 +435,7 @@ public SqlType GetSqlTypeCode(IMapping mapping)
}
catch (Exception e)
{
- throw new MappingException(string.Format("Could not determine type for column {0} of type {1}: {2}",
+ throw new MappingException(string.Format("Could not determine type for column {0} of type {1}: {2}",
_name, type.GetType().FullName, e.GetType().FullName), e);
}
}
@@ -436,7 +443,7 @@ public SqlType GetSqlTypeCode(IMapping mapping)
/// returns quoted name as it would be in the mapping file.
public string GetQuotedName()
{
- return _quoted ? '`' + _name + '`' : _name;
+ return _quoted ? QuoteChar + _name + QuoteChar : _name;
}
public bool IsCaracteristicsDefined()
@@ -463,24 +470,24 @@ public bool IsLengthDefined()
/// Shallow copy, the value is not copied
public object Clone()
{
- Column copy = new Column();
- if (_length.HasValue)
- copy.Length = Length;
- if (_precision.HasValue)
- copy.Precision = Precision;
- if (_scale.HasValue)
- copy.Scale = Scale;
- copy.Value = _value;
- copy.TypeIndex = _typeIndex;
- copy.Name = GetQuotedName();
- copy.IsNullable = _nullable;
- copy.Unique = _unique;
- copy.SqlType = _sqlType;
- copy.SqlTypeCode = _sqlTypeCode;
- copy.UniqueInteger = UniqueInteger; //usually useless
- copy.CheckConstraint = _checkConstraint;
- copy.Comment = _comment;
- copy.DefaultValue = _defaultValue;
+ Column copy = new Column()
+ {
+ _length = _length,
+ _name = _name,
+ _quoted = _quoted,
+ _checkConstraint = _checkConstraint,
+ _comment = _comment,
+ _defaultValue = _defaultValue,
+ _nullable = _nullable,
+ _unique = _unique,
+ _precision = _precision,
+ _scale = _scale,
+ _sqlType = _sqlType,
+ _sqlTypeCode = _sqlTypeCode,
+ _typeIndex = _typeIndex,
+ _value = _value,
+ UniqueInteger = UniqueInteger,
+ };
return copy;
}
diff --git a/src/NHibernate/Mapping/OneToMany.cs b/src/NHibernate/Mapping/OneToMany.cs
index 119398bec67..f2e1746c78a 100644
--- a/src/NHibernate/Mapping/OneToMany.cs
+++ b/src/NHibernate/Mapping/OneToMany.cs
@@ -2,6 +2,7 @@
using System.Collections.Generic;
using NHibernate.Engine;
using NHibernate.Type;
+using NHibernate.Util;
namespace NHibernate.Mapping
{
@@ -47,7 +48,7 @@ public int ColumnSpan
public string ReferencedEntityName
{
get { return referencedEntityName; }
- set { referencedEntityName = value == null ? null : string.Intern(value); }
+ set { referencedEntityName = StringHelper.Intern(value, InternLevel.ReferencedEntityName); }
}
public Table ReferencingTable
@@ -154,4 +155,4 @@ public bool[] ColumnUpdateability
get { throw new InvalidOperationException(); }
}
}
-}
\ No newline at end of file
+}
diff --git a/src/NHibernate/Mapping/PersistentClass.cs b/src/NHibernate/Mapping/PersistentClass.cs
index 202bf463055..8129c8405e2 100644
--- a/src/NHibernate/Mapping/PersistentClass.cs
+++ b/src/NHibernate/Mapping/PersistentClass.cs
@@ -70,7 +70,7 @@ public string ClassName
get { return className; }
set
{
- className = value == null ? null : string.Intern(value);
+ className = StringHelper.Intern(value, InternLevel.ClassName);
mappedClass = null;
}
}
@@ -259,7 +259,7 @@ public virtual IEnumerable DirectSubclasses
public virtual string EntityName
{
get { return entityName; }
- set { entityName = value == null ? null : String.Intern(value); }
+ set { entityName = StringHelper.Intern(value, InternLevel.EntityName, checkPoolIfInternIsDisabled: true); }
}
///
@@ -519,7 +519,7 @@ public virtual IDictionary FilterMap
public string LoaderName
{
get { return loaderName; }
- set { loaderName = value == null ? null : string.Intern(value); }
+ set { loaderName = value == null ? null : StringHelper.Intern(value, InternLevel.LoaderName); }
}
public virtual ISet SynchronizedTables
diff --git a/src/NHibernate/Mapping/Property.cs b/src/NHibernate/Mapping/Property.cs
index 49d29cac0a4..c504ba40add 100644
--- a/src/NHibernate/Mapping/Property.cs
+++ b/src/NHibernate/Mapping/Property.cs
@@ -66,7 +66,7 @@ public IEnumerable ColumnIterator
public string Name
{
get { return name; }
- set { name = value; }
+ set { name = StringHelper.Intern(value, InternLevel.PropertyName); }
}
public bool IsComposite
diff --git a/src/NHibernate/Proxy/DynamicProxy/ProxyFactory.cs b/src/NHibernate/Proxy/DynamicProxy/ProxyFactory.cs
index 1865190f182..0b43a28921e 100644
--- a/src/NHibernate/Proxy/DynamicProxy/ProxyFactory.cs
+++ b/src/NHibernate/Proxy/DynamicProxy/ProxyFactory.cs
@@ -76,9 +76,10 @@ public System.Type CreateProxyType(System.Type baseType, params System.Type[] in
private TypeInfo CreateUncachedProxyType(System.Type baseType, IReadOnlyCollection baseInterfaces)
{
AppDomain currentDomain = AppDomain.CurrentDomain;
- string typeName = string.Format("{0}Proxy", baseType.Name);
- string assemblyName = string.Format("{0}Assembly", typeName);
- string moduleName = string.Format("{0}Module", typeName);
+ const InternLevel internLevel = InternLevel.ProxyType;
+ string typeName = StringHelper.Intern($"{baseType.Name}Proxy", internLevel);
+ string assemblyName = StringHelper.Intern($"{typeName}Assembly", internLevel);
+ string moduleName = StringHelper.Intern($"{typeName}Module", internLevel);
var name = new AssemblyName(assemblyName);
AssemblyBuilder assemblyBuilder = ProxyAssemblyBuilder.DefineDynamicAssembly(currentDomain, name);
diff --git a/src/NHibernate/Proxy/NHibernateProxyBuilder.cs b/src/NHibernate/Proxy/NHibernateProxyBuilder.cs
index 8502d950b33..b2a76d0920a 100644
--- a/src/NHibernate/Proxy/NHibernateProxyBuilder.cs
+++ b/src/NHibernate/Proxy/NHibernateProxyBuilder.cs
@@ -45,9 +45,10 @@ public NHibernateProxyBuilder(MethodInfo getIdentifierMethod, MethodInfo setIden
public TypeInfo CreateProxyType(System.Type baseType, IReadOnlyCollection baseInterfaces)
{
- var typeName = $"{baseType.Name}Proxy";
- var assemblyName = $"{typeName}Assembly";
- var moduleName = $"{typeName}Module";
+ var internLevel = InternLevel.ProxyType;
+ var typeName = StringHelper.Intern($"{baseType.Name}Proxy", internLevel);
+ var assemblyName = StringHelper.Intern($"{typeName}Assembly", internLevel);
+ var moduleName = StringHelper.Intern($"{typeName}Module", internLevel);
var name = new AssemblyName(assemblyName);
@@ -117,11 +118,11 @@ private void CreateProxiedMethod(TypeBuilder typeBuilder, MethodInfo method, Fie
{
ImplementSetIdentifier(typeBuilder, method, lazyInitializerField);
}
- else if (!_overridesEquals && method.Name == "Equals" && method.GetBaseDefinition() == typeof(object).GetMethod("Equals", new[] {typeof(object)}))
+ else if (!_overridesEquals && method.Name == nameof(Equals) && method.GetBaseDefinition() == typeof(object).GetMethod(nameof(Equals), new[] {typeof(object)}))
{
//skip
}
- else if (!_overridesEquals && method.Name == "GetHashCode" && method.GetBaseDefinition() == typeof(object).GetMethod("GetHashCode"))
+ else if (!_overridesEquals && method.Name == nameof(GetHashCode) && method.GetBaseDefinition() == typeof(object).GetMethod(nameof(GetHashCode)))
{
//skip
}
diff --git a/src/NHibernate/SqlCommand/SqlSimpleSelectBuilder.cs b/src/NHibernate/SqlCommand/SqlSimpleSelectBuilder.cs
index de7cbfc10a5..49b30a9bb02 100644
--- a/src/NHibernate/SqlCommand/SqlSimpleSelectBuilder.cs
+++ b/src/NHibernate/SqlCommand/SqlSimpleSelectBuilder.cs
@@ -180,6 +180,11 @@ public virtual SqlSimpleSelectBuilder SetComment(System.String comment)
///
public SqlString ToSqlString()
+ {
+ return ToSqlString(false);
+ }
+
+ public SqlString ToSqlString(bool intern)
{
//TODO: add default capacity
SqlStringBuilder sqlBuilder = new SqlStringBuilder();
@@ -206,7 +211,7 @@ public SqlString ToSqlString()
if (alias != null && !alias.Equals(column))
{
sqlBuilder.Add(" AS ")
- .Add(alias);
+ .Add(alias);
}
commaNeeded = true;
@@ -214,7 +219,7 @@ public SqlString ToSqlString()
sqlBuilder.Add(" FROM ")
- .Add(Dialect.AppendLockHint(lockMode, tableName));
+ .Add(Dialect.AppendLockHint(lockMode, tableName));
sqlBuilder.Add(" WHERE ");
@@ -233,9 +238,9 @@ public SqlString ToSqlString()
sqlBuilder.Add(Dialect.GetForUpdateString(lockMode));
}
- return sqlBuilder.ToSqlString();
+ return sqlBuilder.ToSqlString(intern);
}
#endregion
- }
-}
\ No newline at end of file
+ }
+}
diff --git a/src/NHibernate/SqlCommand/SqlString.cs b/src/NHibernate/SqlCommand/SqlString.cs
index 1e3de9453a5..8fcebd506e1 100644
--- a/src/NHibernate/SqlCommand/SqlString.cs
+++ b/src/NHibernate/SqlCommand/SqlString.cs
@@ -5,6 +5,7 @@
using System.Collections;
using NHibernate.SqlCommand.Parser;
using System.Text.RegularExpressions;
+using NHibernate.Util;
namespace NHibernate.SqlCommand
{
@@ -196,10 +197,10 @@ public SqlString(Parameter parameter)
/// values.
/// The instance is automatically compacted.
public SqlString(params object[] parts)
- : this((IEnumerable