📄 abstractentitypersister.cs
字号:
VersionSelectString);
}
}
protected internal virtual void InitLockers()
{
lockers[LockMode.Read] = GenerateLocker(LockMode.Read);
lockers[LockMode.Upgrade] = GenerateLocker(LockMode.Upgrade);
lockers[LockMode.UpgradeNoWait] = GenerateLocker(LockMode.UpgradeNoWait);
lockers[LockMode.Force] = GenerateLocker(LockMode.Force);
}
protected internal virtual ILockingStrategy GenerateLocker(LockMode lockMode)
{
return factory.Dialect.GetLockingStrategy(this, lockMode);
}
private ILockingStrategy GetLocker(LockMode lockMode)
{
try
{
return lockers[lockMode];
}
catch (KeyNotFoundException)
{
throw new HibernateException(string.Format("LockMode {0} not supported by {1}", lockMode, GetType().FullName));
}
}
public virtual void Lock(object id, object version, object obj, LockMode lockMode, ISessionImplementor session)
{
GetLocker(lockMode).Lock(id, version, obj, session);
}
public virtual string GetRootTableAlias(string drivingAlias)
{
return drivingAlias;
}
public virtual string[] ToColumns(string alias, string propertyName)
{
return propertyMapping.ToColumns(alias, propertyName);
}
public string[] ToColumns(string propertyName)
{
return propertyMapping.GetColumnNames(propertyName);
}
public IType ToType(string propertyName)
{
return propertyMapping.ToType(propertyName);
}
public string[] GetPropertyColumnNames(string propertyName)
{
return propertyMapping.GetColumnNames(propertyName);
}
/// <remarks>
/// Warning:
/// When there are duplicated property names in the subclasses
/// of the class, this method may return the wrong table
/// number for the duplicated subclass property (note that
/// SingleTableEntityPersister defines an overloaded form
/// which takes the entity name.
/// </remarks>
public virtual int GetSubclassPropertyTableNumber(string propertyPath)
{
string rootPropertyName = StringHelper.Root(propertyPath);
IType type = propertyMapping.ToType(rootPropertyName);
if (type.IsAssociationType)
{
IAssociationType assocType = (IAssociationType)type;
if (assocType.UseLHSPrimaryKey)
{
// performance op to avoid the array search
return 0;
}
else if (type.IsCollectionType)
{
// properly handle property-ref-based associations
rootPropertyName = assocType.LHSPropertyName;
}
}
//Enable for HHH-440, which we don't like:
/*if ( type.isComponentType() && !propertyName.equals(rootPropertyName) ) {
String unrooted = StringHelper.unroot(propertyName);
int idx = ArrayHelper.indexOf( getSubclassColumnClosure(), unrooted );
if ( idx != -1 ) {
return getSubclassColumnTableNumberClosure()[idx];
}
}*/
int index = Array.IndexOf(SubclassPropertyNameClosure, rootPropertyName); //TODO: optimize this better!
return index == -1 ? 0 : GetSubclassPropertyTableNumber(index);
}
public virtual Declarer GetSubclassPropertyDeclarer(string propertyPath)
{
int tableIndex = GetSubclassPropertyTableNumber(propertyPath);
if (tableIndex == 0)
{
return Declarer.Class;
}
else if (IsClassOrSuperclassTable(tableIndex))
{
return Declarer.SuperClass;
}
else
{
return Declarer.SubClass;
}
}
public string GenerateTableAlias(string rootAlias, int tableNumber)
{
if (tableNumber == 0)
return rootAlias;
StringBuilder buf = new StringBuilder().Append(rootAlias);
if (!rootAlias.EndsWith("_"))
{
buf.Append('_');
}
return buf.Append(tableNumber).Append('_').ToString();
}
public string[] ToColumns(string name, int i)
{
string alias = GenerateTableAlias(name, GetSubclassPropertyTableNumber(i));
string[] cols = GetSubclassPropertyColumnNames(i);
string[] templates = SubclassPropertyFormulaTemplateClosure[i];
string[] result = new string[cols.Length];
for (int j = 0; j < cols.Length; j++)
{
if (cols[j] == null)
{
result[j] = StringHelper.Replace(templates[j], Template.Placeholder, alias);
}
else
{
result[j] = StringHelper.Qualify(alias, cols[j]);
}
}
return result;
}
private int GetSubclassPropertyIndex(string propertyName)
{
return Array.IndexOf(subclassPropertyNameClosure, propertyName);
}
/// <summary>
/// Get the column names for the numbered property of <em>this</em> class
/// </summary>
public string[] GetPropertyColumnNames(int i)
{
return propertyColumnNames[i];
}
protected int GetPropertyColumnSpan(int i)
{
return propertyColumnSpans[i];
}
protected bool HasFormulaProperties
{
get { return hasFormulaProperties; }
}
public FetchMode GetFetchMode(int i)
{
return subclassPropertyFetchModeClosure[i];
}
public CascadeStyle GetCascadeStyle(int i)
{
return subclassPropertyCascadeStyleClosure[i];
}
public IType GetSubclassPropertyType(int i)
{
return subclassPropertyTypeClosure[i];
}
public string GetSubclassPropertyName(int i)
{
return subclassPropertyNameClosure[i];
}
public int CountSubclassProperties()
{
return subclassPropertyTypeClosure.Length;
}
public string[] GetSubclassPropertyColumnNames(int i)
{
return subclassPropertyColumnNameClosure[i];
}
public bool IsDefinedOnSubclass(int i)
{
return propertyDefinedOnSubclass[i];
}
public string[] GetSubclassPropertyColumnAliases(string propertyName, string suffix)
{
string[] rawAliases;
if (!subclassPropertyAliases.TryGetValue(propertyName,out rawAliases))
return null;
string[] result = new string[rawAliases.Length];
for (int i = 0; i < rawAliases.Length; i++)
result[i] = new Alias(suffix).ToUnquotedAliasString(rawAliases[i], Factory.Dialect);
return result;
}
public string[] GetSubclassPropertyColumnNames(string propertyName)
{
//TODO: should we allow suffixes on these ?
string[] result;
subclassPropertyColumnNames.TryGetValue(propertyName, out result);
return result;
}
/// <summary>
/// Must be called by subclasses, at the end of their constructors
/// </summary>
protected void InitSubclassPropertyAliasesMap(PersistentClass model)
{
// ALIASES
InternalInitSubclassPropertyAliasesMap(null, model.SubclassPropertyClosureIterator);
// aliases for identifier ( alias.id ); skip if the entity defines a non-id property named 'id'
if (!entityMetamodel.HasNonIdentifierPropertyNamedId)
{
subclassPropertyAliases[EntityPersister.EntityID] = identifierAliases;
subclassPropertyColumnNames[EntityPersister.EntityID] = IdentifierColumnNames;
}
// aliases named identifier ( alias.idname )
if (HasIdentifierProperty)
{
subclassPropertyAliases[IdentifierPropertyName] = IdentifierAliases;
subclassPropertyColumnNames[IdentifierPropertyName] = IdentifierColumnNames;
}
// aliases for composite-id's
if (IdentifierType.IsComponentType)
{
// Fetch embedded identifiers propertynames from the "virtual" identifier component
IAbstractComponentType componentId = (IAbstractComponentType)IdentifierType;
string[] idPropertyNames = componentId.PropertyNames;
string[] idAliases = IdentifierAliases;
string[] idColumnNames = IdentifierColumnNames;
for (int i = 0; i < idPropertyNames.Length; i++)
{
if (entityMetamodel.HasNonIdentifierPropertyNamedId)
{
subclassPropertyAliases[EntityPersister.EntityID + "." + idPropertyNames[i]] = new string[] { idAliases[i] };
subclassPropertyColumnNames[EntityPersister.EntityID + "." + IdentifierPropertyName + "." + idPropertyNames[i]] = new string[] { idColumnNames[i] };
}
// if (hasIdentifierProperty() && !ENTITY_ID.equals( getIdentifierPropertyName() ) ) {
if (HasIdentifierProperty)
{
subclassPropertyAliases[IdentifierPropertyName + "." + idPropertyNames[i]] = new string[] { idAliases[i] };
subclassPropertyColumnNames[IdentifierPropertyName + "." + idPropertyNames[i]] = new string[] { idColumnNames[i] };
}
else
{
// embedded composite ids ( alias.idname1, alias.idname2 )
subclassPropertyAliases[idPropertyNames[i]] = new string[] { idAliases[i] };
subclassPropertyColumnNames[idPropertyNames[i]] = new string[] { idColumnNames[i] };
}
}
}
if (entityMetamodel.IsPolymorphic)
{
subclassPropertyAliases[EntityClass] = new string[] { DiscriminatorAlias };
subclassPropertyColumnNames[EntityClass] = new string[] { DiscriminatorColumnName };
}
}
private void InternalInitSubclassPropertyAliasesMap(string path, IEnumerable<Property> col)
{
foreach (Property prop in col)
{
string propName = path == null ? prop.Name : path + "." + prop.Name;
if (prop.IsComposite)
{
Component component = (Component)prop.Value;
InternalInitSubclassPropertyAliasesMap(propName, component.PropertyIterator);
}
else
{
string[] aliases = new string[prop.ColumnSpan];
string[] cols = new string[prop.ColumnSpan];
int l = 0;
foreach (ISelectable thing in prop.ColumnIterator)
{
aliases[l] = thing.GetAlias(Factory.Dialect, prop.Value.Table);
cols[l] = thing.GetText(Factory.Dialect);
l++;
}
subclassPropertyAliases[propName] = aliases;
subclassPropertyColumnNames[propName] = cols;
}
}
}
public object LoadByUniqueKey(string propertyName, object uniqueKey, ISessionImplementor session)
{
return GetAppropriateUniqueKeyLoader(propertyName, session.EnabledFilters).LoadByUniqueKey(session, uniqueKey);
}
private EntityLoader GetAppropriateUniqueKeyLoader(string propertyName, IDictionary<string, IFilter> enabledFilters)
{
//ugly little workaround for fact that createUniqueKeyLoaders() does not handle component properties
bool useStaticLoader = (enabledFilters == null || (enabledFilters.Count == 0)) && propertyName.IndexOf('.') < 0;
if (useStaticLoader)
{
return (EntityLoader)uniqueKeyLoaders[propertyName];
}
else
{
return CreateUniqueKeyLoader(propertyMapping.ToType(propertyName), propertyMapping.ToColumns(propertyName), enabledFilters);
}
}
public int GetPropertyIndex(string propertyName)
{
return entityMetamodel.GetPropertyIndex(propertyName);
}
protected void CreateUniqueKeyLoaders()
{
IType[] propertyTypes = PropertyTypes;
string[] propertyNames = PropertyNames;
for (int i = 0; i < entityMetamodel.PropertySpan; i++)
{
if (propertyUniqueness[i])
{
//don't need filters for the static loaders
uniqueKeyLoaders[propertyNames[i]] =
CreateUniqueKeyLoader(propertyTypes[i], GetPropertyColumnNames(i),
new CollectionHelper.EmptyMapClass<string, IFilter>());
}
}
}
private EntityLoader CreateUniqueKeyLoader(IType uniqueKeyType, string[] columns, IDictionary<string, IFilter> enabledFilters)
{
if (uniqueKeyType.IsEntityType)
{
string className = ((EntityType)uniqueKeyType).GetAssociatedEntityName();
uniqueKeyType = Factory.GetEntityPersister(className).IdentifierType;
}
return new EntityLoader(this, columns, uniqueKeyType, 1, LockMode.None, Factory, enabledFilters);
}
protected string GetSQLWhereString(string alias)
{
return StringHelper.Replace(sqlWhereStringTemplate, Template.Placeholder, alias);
}
protected bool HasWhere
{
get { return !string.IsNullOrEmpty(sqlWhereString); }
}
private void InitOrdinaryPropertyPaths(IMapping mapping)
{
for (int i = 0; i < SubclassPropertyNameClosure.Length; i++)
{
propertyMapping.InitPropertyPaths(
SubclassPropertyNameClosure[i],
SubclassPropertyTypeClosure[i],
SubclassPropertyColumnNameClosure[i],
SubclassPropertyFormulaTemplateClosure[i],
mapping);
}
}
private void InitIdentifierPropertyPaths(IMapping mapping)
{
string idProp = IdentifierPropertyName;
if (idProp != null)
{
propertyMapping.InitPropertyPaths(idProp, IdentifierType, IdentifierColumnNames, null, mapping);
}
if (entityMetamodel.IdentifierProperty.IsEmbedded)
{
propertyMapping.InitPropertyPaths(null, IdentifierType, IdentifierColumnNames, null, mapping);
}
if (!entityMetamodel.HasNonIdentifierPropertyNamedId)
{
propertyMapping.InitPropertyPaths(EntityPersister.EntityID, IdentifierType, IdentifierColumnNames, null, mapping);
}
}
private void InitDiscriminatorPropertyPath()
{
propertyMapping.InitPropertyPaths(EntityClass, DiscriminatorType, new string[] {DiscriminatorColumnName},
new string[] {DiscriminatorFormulaTemplate}, Factory);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -