Is there better way to find that object isn't been referenced by any other object than this?
Right now i'm finding all object that have Attachment list and then doing subqueries to see if attachment is in their list or not.
Code:
public static void DeleteOrphanAttachments(ISession s)
{
IDictionary classes = s.SessionFactory.GetAllClassMetadata();
List<Type> queryTypes = new List<Type>();
List<string> propertyNames = new List<string>();
foreach (DictionaryEntry entry in classes)
{
SingleTableEntityPersister abstractClass = (SingleTableEntityPersister)entry.Value;
for (int i = 0; i < abstractClass.PropertyTypes.Length; i++)
{
if (abstractClass.PropertyTypes[i].ReturnedClass.UnderlyingSystemType.Equals(typeof(IList<Attachment>)))
{
bool insert = true;
if (abstractClass.MappedSuperclass != null)
{
SingleTableEntityPersister superClass = (SingleTableEntityPersister)classes[abstractClass.MappedSuperclass];
if (superClass.TableName == abstractClass.TableName)
{
foreach (string name in superClass.PropertyNames)
{
if (name == abstractClass.PropertyNames[i])
{
insert = false;
}
}
}
}
if (insert)
{
queryTypes.Add((Type)entry.Key);
propertyNames.Add(abstractClass.PropertyNames[i]);
}
}
}
}
if (queryTypes.Count > 0)
{
ICriteria crit = s.CreateCriteria(typeof(Attachment), "attachment");
for (int i = 0; i < queryTypes.Count; i++)
{
DetachedCriteria detachedQuery = DetachedCriteria.For(queryTypes[i])
.SetProjection(Projections.RowCount())
.CreateAlias(propertyNames[i], propertyNames[i].ToLower())
.Add(Property.ForName(propertyNames[i].ToLower() + ".Id").EqProperty("attachment.Id"));
crit = crit.Add(Subqueries.Eq(0, detachedQuery));
}
IList<Attachment> attachments = crit.List<Attachment>();
foreach (Attachment att in attachments)
{
s.Delete(att);
}
}
}