📄 abstractcollectionpersister.cs
字号:
// for non-arrays, we don't need to know the element class
elementClass = null;
}
if (elementType.IsComponentType)
{
elementPropertyMapping =
new CompositeElementPropertyMapping(elementColumnNames, elementFormulaTemplates,
(IAbstractComponentType)elementType, factory);
}
else if (!elementType.IsEntityType)
{
elementPropertyMapping = new ElementPropertyMapping(elementColumnNames, elementType);
}
else
{
elementPropertyMapping = elementPersister as IPropertyMapping;
if (elementPropertyMapping == null)
elementPropertyMapping = new ElementPropertyMapping(elementColumnNames, elementType);
}
// Handle any filters applied to this collection
filterHelper = new FilterHelper(collection.FilterMap, dialect, factory.SQLFunctionRegistry);
// Handle any filters applied to this collection for many-to-many
manyToManyFilterHelper = new FilterHelper(collection.ManyToManyFilterMap, dialect, factory.SQLFunctionRegistry);
manyToManyWhereString = !string.IsNullOrEmpty(collection.ManyToManyWhere)
? "( " + collection.ManyToManyWhere + " )"
: null;
manyToManyWhereTemplate = manyToManyWhereString == null
? null
: Template.RenderWhereStringTemplate(manyToManyWhereString, factory.Dialect,
factory.SQLFunctionRegistry);
manyToManyOrderByString = collection.ManyToManyOrdering;
manyToManyOrderByTemplate = manyToManyOrderByString == null
? null
: Template.RenderOrderByStringTemplate(manyToManyOrderByString, factory.Dialect,
factory.SQLFunctionRegistry);
InitCollectionPropertyMap();
}
public void PostInstantiate()
{
initializer = queryLoaderName == null
? CreateCollectionInitializer(new CollectionHelper.EmptyMapClass<string, IFilter>())
: new NamedQueryCollectionInitializer(queryLoaderName, this);
}
protected void LogStaticSQL()
{
if (log.IsDebugEnabled)
{
log.Debug("Static SQL for collection: " + Role);
if (SqlInsertRowString != null)
log.Debug(" Row insert: " + SqlInsertRowString.Text);
if (SqlUpdateRowString != null)
log.Debug(" Row update: " + SqlUpdateRowString.Text);
if (SqlDeleteRowString != null)
log.Debug(" Row delete: " + SqlDeleteRowString.Text);
if (SqlDeleteString != null)
log.Debug(" One-shot delete: " + SqlDeleteString.Text);
}
}
public void Initialize(object key, ISessionImplementor session)
{
GetAppropriateInitializer(key, session).Initialize(key, session);
}
protected ICollectionInitializer GetAppropriateInitializer(object key, ISessionImplementor session)
{
if (queryLoaderName != null)
{
//if there is a user-specified loader, return that
//TODO: filters!?
return initializer;
}
ICollectionInitializer subselectInitializer = GetSubselectInitializer(key, session);
if (subselectInitializer != null)
{
return subselectInitializer;
}
else if (session.EnabledFilters.Count == 0)
{
return initializer;
}
else
{
return CreateCollectionInitializer(session.EnabledFilters);
}
}
private ICollectionInitializer GetSubselectInitializer(object key, ISessionImplementor session)
{
if (!IsSubselectLoadable)
{
return null;
}
IPersistenceContext persistenceContext = session.PersistenceContext;
SubselectFetch subselect = persistenceContext.BatchFetchQueue.GetSubselect(new EntityKey(key, OwnerEntityPersister, session.EntityMode));
if (subselect == null)
{
return null;
}
else
{
// Take care of any entities that might have
// been evicted!
ArrayList keysToRemove = new ArrayList();
foreach (EntityKey entityKey in subselect.Result)
{
if (!persistenceContext.ContainsEntity(entityKey))
{
keysToRemove.Add(entityKey);
}
}
subselect.Result.RemoveAll(keysToRemove);
// Run a subquery loader
return CreateSubselectInitializer(subselect, session);
}
}
protected abstract ICollectionInitializer CreateSubselectInitializer(SubselectFetch subselect,
ISessionImplementor session);
protected abstract ICollectionInitializer CreateCollectionInitializer(IDictionary<string, IFilter> enabledFilters);
public bool HasCache
{
get { return cache != null; }
}
public string GetSQLWhereString(string alias)
{
return StringHelper.Replace(sqlWhereStringTemplate, Template.Placeholder, alias);
}
public string GetSQLOrderByString(string alias)
{
return HasOrdering ? StringHelper.Replace(sqlOrderByStringTemplate, Template.Placeholder, alias) : string.Empty;
}
public string GetManyToManyOrderByString(string alias)
{
if (IsManyToMany && manyToManyOrderByString != null)
{
return StringHelper.Replace(manyToManyOrderByTemplate, Template.Placeholder, alias);
}
else
{
return string.Empty;
}
}
public bool HasOrdering
{
get { return hasOrder; }
}
public bool HasManyToManyOrdering
{
get { return IsManyToMany && manyToManyOrderByTemplate != null; }
}
public bool HasWhere
{
get { return hasWhere; }
}
/// <summary>
/// Reads the Element from the IDataReader. The IDataReader will probably only contain
/// the id of the Element.
/// </summary>
/// <remarks>See ReadElementIdentifier for an explanation of why this method will be depreciated.</remarks>
public object ReadElement(IDataReader rs, object owner, string[] aliases, ISessionImplementor session)
{
return ElementType.NullSafeGet(rs, aliases, session, owner);
}
public object ReadIndex(IDataReader rs, string[] aliases, ISessionImplementor session)
{
object index = IndexType.NullSafeGet(rs, aliases, session, null);
if (index == null)
{
throw new HibernateException("null index column for collection: " + role);
}
index = DecrementIndexByBase(index);
return index;
}
public object DecrementIndexByBase(object index)
{
if (baseIndex != 0)
index = (int) index - baseIndex;
return index;
}
public object ReadIdentifier(IDataReader rs, string alias, ISessionImplementor session)
{
object id = IdentifierType.NullSafeGet(rs, alias, session, null);
if (id == null)
throw new HibernateException("null identifier column for collection: " + role);
return id;
}
public object ReadKey(IDataReader dr, string[] aliases, ISessionImplementor session)
{
return KeyType.NullSafeGet(dr, aliases, session, null);
}
protected int WriteKey(IDbCommand st, object id, int i, ISessionImplementor session)
{
if (id == null)
throw new ArgumentNullException("id", "Null key for collection: " + role);
KeyType.NullSafeSet(st, id, i, session);
return i + keyColumnAliases.Length;
}
protected int WriteElement(IDbCommand st, object elt, int i, ISessionImplementor session)
{
ElementType.NullSafeSet(st, elt, i, elementColumnIsSettable, session);
return i + ArrayHelper.CountTrue(elementColumnIsSettable);
}
protected int WriteIndex(IDbCommand st, object idx, int i, ISessionImplementor session)
{
IndexType.NullSafeSet(st, IncrementIndexByBase(idx), i, indexColumnIsSettable, session);
return i + ArrayHelper.CountTrue(indexColumnIsSettable);
}
protected object IncrementIndexByBase(object index)
{
if (baseIndex != 0)
index = (int) index + baseIndex;
return index;
}
protected int WriteElementToWhere(IDbCommand st, object elt, int i, ISessionImplementor session)
{
if (elementIsPureFormula)
throw new AssertionFailure("cannot use a formula-based element in the where condition");
ElementType.NullSafeSet(st, elt, i, elementColumnIsInPrimaryKey, session);
return i + elementColumnAliases.Length;
}
protected int WriteIndexToWhere(IDbCommand st, object index, int i, ISessionImplementor session)
{
if (indexContainsFormula)
throw new AssertionFailure("cannot use a formula-based index in the where condition");
IndexType.NullSafeSet(st, IncrementIndexByBase(index), i, session);
return i + indexColumnAliases.Length;
}
protected int WriteIdentifier(IDbCommand st, object idx, int i, ISessionImplementor session)
{
IdentifierType.NullSafeSet(st, idx, i, session);
return i + 1;
}
public string[] GetKeyColumnAliases(string suffix)
{
return new Alias(suffix).ToAliasStrings(keyColumnAliases, dialect);
}
public string[] GetElementColumnAliases(string suffix)
{
return new Alias(suffix).ToAliasStrings(elementColumnAliases, dialect);
}
public string[] GetIndexColumnAliases(string suffix)
{
if (hasIndex)
return new Alias(suffix).ToAliasStrings(indexColumnAliases, dialect);
else
return null;
}
public string GetIdentifierColumnAlias(string suffix)
{
if (hasIdentifier)
return new Alias(suffix).ToAliasString(identifierColumnAlias, dialect);
else
return null;
}
public string SelectFragment(string alias, string columnSuffix)
{
SelectFragment frag = GenerateSelectFragment(alias, columnSuffix);
AppendElementColumns(frag, alias);
AppendIndexColumns(frag, alias);
AppendIdentifierColumns(frag, alias);
return frag.ToSqlStringFragment(false);
}
private SqlString GenerateSelectSizeString(bool isIntegerIndexed)
{
string selectValue = isIntegerIndexed ? "max(" + IndexColumnNames[0] + ") + 1" : "count(" + ElementColumnNames[0] + ")"; //sets, maps, bags
return
new SqlSimpleSelectBuilder(dialect, factory)
.SetTableName(TableName)
.AddWhereFragment(KeyColumnNames, KeyType, "=")
.AddColumn(selectValue)
.ToSqlString();
}
private SqlString GenerateDetectRowByIndexString()
{
if (!hasIndex)
return null;
// TODO NH: may be we need something else when Index is mixed with Formula
return
new SqlSimpleSelectBuilder(dialect, factory).SetTableName(TableName).AddWhereFragment(KeyColumnNames, KeyType, "=").
AddWhereFragment(IndexColumnNames, IndexType, "=").AddWhereFragment(indexFormulas, IndexType, "=").AddColumn("1").
ToSqlString();
}
private SqlString GenerateSelectRowByIndexString()
{
if (!hasIndex)
return null;
return
new SqlSimpleSelectBuilder(dialect, factory).SetTableName(TableName).AddWhereFragment(KeyColumnNames, KeyType, "=")
.AddWhereFragment(IndexColumnNames, IndexType, "=").AddWhereFragment(indexFormulas, IndexType, "=")
.AddColumns(ElementColumnNames, elementColumnAliases).AddColumns(indexFormulas, indexColumnAliases).ToSqlString();
}
private SqlString GenerateDetectRowByElementString()
{
return
new SqlSimpleSelectBuilder(dialect, factory).SetTableName(TableName).AddWhereFragment(KeyColumnNames, KeyType, "=").
AddWhereFragment(ElementColumnNames, ElementType, "=").AddWhereFragment(elementFormulas, ElementType, "=").
AddColumn("1").ToSqlString();
}
protected virtual SelectFragment GenerateSelectFragment(string alias, string columnSuffix)
{
return new SelectFragment(dialect)
.SetSuffix(columnSuffix)
.AddColumns(alias, keyColumnNames, keyColumnAliases);
}
protected virtual void AppendElementColumns(SelectFragment frag, string elemAlias)
{
for (int i = 0; i < elementColumnIsSettable.Length; i++)
{
if (elementColumnIsSettable[i])
{
frag.AddColumn(elemAlias, elementColumnNames[i], elementColumnAliases[i]);
}
else
{
frag.AddFormula(elemAlias, elementFormulaTemplates[i], elementColumnAliases[i]);
}
}
}
protected virtual void AppendIndexColumns(SelectFragment frag, string alias)
{
if (hasIndex)
{
for (int i = 0; i < indexColumnIsSettable.Length; i++)
{
if (indexColumnIsSettable[i])
frag.AddColumn(alias, indexColumnNames[i], indexColumnAliases[i]);
else
frag.AddFormula(alias, indexFormulaTemplates[i], indexColumnAliases[i]);
}
}
}
protected virtual void AppendIdentifierColumns(SelectFragment frag, string alias)
{
if (hasIdentifier)
{
frag.AddColumn(alias, identifierColumnName, identifierColumnAlias);
}
}
public string[] IndexColumnNames
{
get { return indexColumnNames; }
}
public string[] GetIndexColumnNames(string alias)
{
return Qualify(alias, indexColumnNames, indexFormulaTemplates);
}
public string[] GetElementColumnNames(string alias)
{
return Qualify(alias, elementColumnNames, elementFormulaTemplates);
}
private static string[] Qualify(string alias, string[] columnNames, string[] formulaTemplates)
{
int span = columnNames.Length;
string[] result = new string[span];
for (int i = 0; i < span; i++)
{
if (columnNames[i] == null)
result[i] = StringHelper.Replace(formulaTemplates[i], Template.Placeholder, alias);
else
result[i] = StringHelper.Qualify(alias, columnNames[i]);
}
return result;
}
public string[] ElementColumnNames
{
get { return elementColumnNames; }
}
public bool HasIndex
{
get { return hasIndex; }
}
public virtual string TableName
{
get { return qualifiedTableName; }
}
public void Remove(object id, ISessionImplementor session)
{
if (!isInverse && RowDeleteEnabled)
{
if (log.IsDebugEnabled)
{
log.Debug("Deleting collection: " + MessageHelper.InfoString(this, id, Factory));
}
// Remove all the old entries
try
{
int offset = 0;
IExpectation expectation = Expectations.AppropriateExpectation(DeleteAllCheckStyle);
//bool callable = DeleteAllCallable;
bool useBatch = expectation.CanBeBatched;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -