diff --git a/src/NHibernate/Loader/Loader.cs b/src/NHibernate/Loader/Loader.cs
index ad3b5109021..3619a767a1c 100644
--- a/src/NHibernate/Loader/Loader.cs
+++ b/src/NHibernate/Loader/Loader.cs
@@ -82,7 +82,8 @@ public sealed class QueryCacheInfo
///
/// Caches subclass entity aliases for given persister index in and subclass entity name
///
- private readonly ConcurrentDictionary, string[][]> _subclassEntityAliasesMap = new ConcurrentDictionary, string[][]>();
+ private readonly Lazy, string[][]>> _subclassEntityAliasesMap =
+ new(() => new ConcurrentDictionary, string[][]>());
protected Loader(ISessionFactoryImplementor factory)
{
@@ -1322,7 +1323,7 @@ private void LoadFromResultSet(DbDataReader rs, int i, object obj, ILoadable per
private string[][] GetSubclassEntityAliases(int i, ILoadable persister)
{
var cacheKey = System.Tuple.Create(i, persister.EntityName);
- return _subclassEntityAliasesMap.GetOrAdd(
+ return _subclassEntityAliasesMap.Value.GetOrAdd(
cacheKey,
k => EntityAliases[i].GetSuffixedPropertyAliases(persister));
}
diff --git a/src/NHibernate/Mapping/Constraint.cs b/src/NHibernate/Mapping/Constraint.cs
index 5647d4f4906..28ba203fc2b 100644
--- a/src/NHibernate/Mapping/Constraint.cs
+++ b/src/NHibernate/Mapping/Constraint.cs
@@ -15,7 +15,7 @@ namespace NHibernate.Mapping
public abstract class Constraint : IRelationalModel
{
private string name;
- private readonly List columns = new List();
+ private readonly List columns = new List(1);
private Table table;
///
diff --git a/src/NHibernate/Mapping/ForeignKey.cs b/src/NHibernate/Mapping/ForeignKey.cs
index 3d33a3423f7..1359b51c752 100644
--- a/src/NHibernate/Mapping/ForeignKey.cs
+++ b/src/NHibernate/Mapping/ForeignKey.cs
@@ -2,6 +2,7 @@
using System.Text;
using NHibernate.Util;
using System;
+using System.Linq;
namespace NHibernate.Mapping
{
@@ -14,7 +15,7 @@ public class ForeignKey : Constraint
private Table referencedTable;
private string referencedEntityName;
private bool cascadeDeleteEnabled;
- private readonly List referencedColumns = new List();
+ private List referencedColumns;
///
/// Generates the SQL string to create the named Foreign Key Constraint in the database.
@@ -26,29 +27,26 @@ public class ForeignKey : Constraint
///
/// A string that contains the SQL to create the named Foreign Key Constraint.
///
- public override string SqlConstraintString(Dialect.Dialect d, string constraintName, string defaultCatalog, string defaultSchema)
- {
- string[] cols = new string[ColumnSpan];
- string[] refcols = new string[ColumnSpan];
- int i = 0;
- IEnumerable refiter;
- if (IsReferenceToPrimaryKey)
- refiter = referencedTable.PrimaryKey.ColumnIterator;
- else
- refiter = referencedColumns;
- foreach (Column column in ColumnIterator)
- {
- cols[i] = column.GetQuotedName(d);
- i++;
- }
+ public override string SqlConstraintString(
+ Dialect.Dialect d,
+ string constraintName,
+ string defaultCatalog,
+ string defaultSchema)
+ {
+ var refiter = IsReferenceToPrimaryKey
+ ? referencedTable.PrimaryKey.Columns
+ : referencedColumns;
+
+ var cols = Columns.ToArray(column => column.GetQuotedName(d));
+ var refcols = refiter.ToArray(column => column.GetQuotedName(d));
+
+ string result = d.GetAddForeignKeyConstraintString(
+ constraintName,
+ cols,
+ referencedTable.GetQualifiedName(d, defaultCatalog, defaultSchema),
+ refcols,
+ IsReferenceToPrimaryKey);
- i = 0;
- foreach (Column column in refiter)
- {
- refcols[i] = column.GetQuotedName(d);
- i++;
- }
- string result = d.GetAddForeignKeyConstraintString(constraintName, cols, referencedTable.GetQualifiedName(d, defaultCatalog, defaultSchema), refcols, IsReferenceToPrimaryKey);
return cascadeDeleteEnabled && d.SupportsCascadeDelete ? result + " on delete cascade" : result;
}
@@ -172,40 +170,24 @@ public virtual void AddReferencedColumns(IEnumerable referencedColumnsIt
private void AddReferencedColumn(Column column)
{
+ referencedColumns ??= new List(1);
if (!referencedColumns.Contains(column))
referencedColumns.Add(column);
}
internal void AddReferencedTable(PersistentClass referencedClass)
{
- if (referencedColumns.Count > 0)
- {
- referencedTable = referencedColumns[0].Value.Table;
- }
- else
- {
- referencedTable = referencedClass.Table;
- }
+ referencedTable = IsReferenceToPrimaryKey ? referencedClass.Table : referencedColumns[0].Value.Table;
}
public override string ToString()
{
- if (!IsReferenceToPrimaryKey)
- {
- var result = new StringBuilder();
- result.Append(GetType().FullName)
- .Append('(')
- .Append(Table.Name)
- .Append(string.Join(", ", Columns))
- .Append(" ref-columns:")
- .Append('(')
- .Append(string.Join(", ", ReferencedColumns))
- .Append(") as ")
- .Append(Name);
- return result.ToString();
- }
+ if (IsReferenceToPrimaryKey)
+ return base.ToString();
- return base.ToString();
+ var columns = string.Join(", ", Columns);
+ var refColumns = string.Join(", ", referencedColumns);
+ return $"{GetType().FullName}({Table.Name}{columns} ref-columns:({refColumns}) as {Name}";
}
public bool HasPhysicalConstraint
@@ -218,7 +200,11 @@ public bool HasPhysicalConstraint
public IList ReferencedColumns
{
- get { return referencedColumns; }
+ get
+ {
+ referencedColumns ??= new List(1);
+ return referencedColumns;
+ }
}
public string ReferencedEntityName
@@ -228,10 +214,7 @@ public string ReferencedEntityName
}
/// Does this foreignkey reference the primary key of the reference table
- public bool IsReferenceToPrimaryKey
- {
- get { return referencedColumns.Count == 0; }
- }
+ public bool IsReferenceToPrimaryKey => referencedColumns == null || referencedColumns.Count == 0;
public string GeneratedConstraintNamePrefix => "FK_";
@@ -242,12 +225,7 @@ public override bool IsGenerated(Dialect.Dialect dialect)
if (dialect.SupportsNullInUnique || IsReferenceToPrimaryKey)
return true;
- foreach (var column in ReferencedColumns)
- {
- if (column.IsNullable)
- return false;
- }
- return true;
+ return referencedColumns.All(column => !column.IsNullable);
}
}
}
diff --git a/src/NHibernate/Mapping/Index.cs b/src/NHibernate/Mapping/Index.cs
index a29ec92152a..7e8c17a6fd6 100644
--- a/src/NHibernate/Mapping/Index.cs
+++ b/src/NHibernate/Mapping/Index.cs
@@ -14,7 +14,7 @@ namespace NHibernate.Mapping
public class Index : IRelationalModel
{
private Table table;
- private readonly List columns = new List();
+ private readonly List columns = new List(1);
private string name;
public static string BuildSqlCreateIndexString(Dialect.Dialect dialect, string name, Table table,
diff --git a/src/NHibernate/Mapping/SimpleValue.cs b/src/NHibernate/Mapping/SimpleValue.cs
index 0f9f9a7f084..b63e4ceb984 100644
--- a/src/NHibernate/Mapping/SimpleValue.cs
+++ b/src/NHibernate/Mapping/SimpleValue.cs
@@ -15,7 +15,7 @@ namespace NHibernate.Mapping
[Serializable]
public class SimpleValue : IKeyValue
{
- private readonly List columns = new List();
+ private readonly List columns = new List(1);
private IType type;
private IDictionary typeParameters;
diff --git a/src/NHibernate/Mapping/Table.cs b/src/NHibernate/Mapping/Table.cs
index 5311ece174d..8c9b9d0f761 100644
--- a/src/NHibernate/Mapping/Table.cs
+++ b/src/NHibernate/Mapping/Table.cs
@@ -1064,9 +1064,12 @@ internal ForeignKeyKey(IEnumerable columns, string referencedClassName,
{
this.referencedClassName = referencedClassName;
this.columns = new List(columns);
+ this.columns.TrimExcess();
+
if (referencedColumns != null)
{
this.referencedColumns = new List(referencedColumns);
+ this.referencedColumns.TrimExcess();
}
else
{
diff --git a/src/NHibernate/SqlCommand/SqlString.cs b/src/NHibernate/SqlCommand/SqlString.cs
index b9576d0aa76..8f5a1656382 100644
--- a/src/NHibernate/SqlCommand/SqlString.cs
+++ b/src/NHibernate/SqlCommand/SqlString.cs
@@ -215,6 +215,9 @@ internal SqlString(IEnumerable