It is possible to create custom indexes based on either BaseSingleIndex or BaseCompositeIndex. Below is the source code of the Single Index as an example.
/// <summary> /// An index used for a single type. /// </summary> /// <typeparam name="T"></typeparam> /// <typeparam name="TIndex"></typeparam> public class SingleIndex<T, TIndex> : BaseSingleIndex<T,TIndex> where T : class, new()
{
Variables protected Dictionary<TIndex, SingleIndexRecord<T, TIndex>> UniqueItems = new Dictionary<TIndex, SingleIndexRecord<T, TIndex>>(); protected List<SingleIndexRecord<T, TIndex>> NonUniqueItems = new List<SingleIndexRecord<T, TIndex>>();#region
#endregion
#region
Properties /// <summary> /// Used for serialization and deserialization. A dictionary with the primary key for the key, and the index for the value /// </summary> public override Dictionary<long, TIndex> SerializedDictionary{
get { return NonUniqueItems.ToDictionary(item => item.PrimaryKey, item => item.Index); } set
{
new List<SingleIndexRecord<T, TIndex>>(value.Count); if (Style == IndexStyle.Unique)NonUniqueItems =
{
new Dictionary<TIndex, SingleIndexRecord<T, TIndex>>(value.Count);UniqueItems =
}
foreach (SingleIndexRecord<T, TIndex> record in value.Select(item => new SingleIndexRecord<T, TIndex>(this, item.Key, item.Value))){
if (Style == IndexStyle.Unique)NonUniqueItems.Add(record);
{
UniqueItems.Add(record.Index, record);
}
}
}
}
#endregion
#region
Methods /// <summary> /// Clear all lazy loaded values /// </summary> public override void ClearLazyLoadedValues(){
foreach (var singleIndexRecord in NonUniqueItems)
{
null;singleIndexRecord.LazyValue =
}
}
/// <summary> /// Clear all the items in the index and set IsDirty to true /// </summary> public override void Clear(){
true;IsDirty =
NeedsSorted =
false;UniqueItems.Clear();
NonUniqueItems.Clear();
}
/// <summary> /// Insert an index value into the index. It is assumed that it has already been checked for uniqueness /// </summary> /// <param name="primaryKey"></param> /// <param name="indexValue"></param> public override void Insert(long primaryKey, object indexValue){
Common.ChangeType(indexValue, typeof(object), typeof(TIndex)); SingleIndexRecord<T, TIndex> indexRecord = new SingleIndexRecord<T, TIndex>(this, primaryKey, valueToInsert);TIndex valueToInsert = (TIndex)
IsDirty =
true;NeedsSorted =
true; if (Style == IndexStyle.Unique){
if (UniqueItems.ContainsKey(valueToInsert))
throw new NinjaDbProException(Common.BuildUniqueIndexViolationMessage(indexValue, primaryKey, ClassName, IndexName));
UniqueItems.Add(valueToInsert, indexRecord);
}
NonUniqueItems.Add(indexRecord);
}
/// <summary> /// Update an index value by the primary key /// </summary> /// <param name="primaryKey"></param> /// <param name="indexValue"></param> public override void Update(long primaryKey, object indexValue)
{
if (Style == IndexStyle.Unique)
{
UpdateUniqueIndex(primaryKey, indexValue);
}
UpdateIndexRecords(primaryKey, indexValue);
}
private void UpdateUniqueIndex(long primaryKey, object indexValue){
Common.ChangeType(indexValue, typeof(object), typeof(TIndex)); if (UniqueItems.ContainsKey(valueToUpdate))TIndex valueToUpdate = (TIndex)
{
//No change if (UniqueItems[valueToUpdate].PrimaryKey == primaryKey)
return;
string msg = Common.BuildUniqueIndexViolationMessage(indexValue.ToString(), primaryKey, ClassName,
IndexName);
throw new NinjaDbProException(msg);
}
bool found = false;
TIndex existingIndexValue = default(TIndex);
//Remove existing item
foreach (var keyValuePair in UniqueItems){
if (keyValuePair.Value.PrimaryKey == primaryKey){
found =
true;existingIndexValue = keyValuePair.Key;
break;}
}
if (found)
SingleIndexRecord<T, TIndex> indexRecord = new SingleIndexRecord<T, TIndex>(this, primaryKey, valueToUpdate);UniqueItems.Remove(existingIndexValue);
UniqueItems.Add(valueToUpdate, indexRecord);
IsDirty =
true;}
private void UpdateIndexRecords(long primaryKey, object indexValue){
TIndex valueToUpdate = (TIndex)
Common.ChangeType(indexValue, typeof(object), typeof(TIndex)); SingleIndexRecord<T, TIndex> indexRecord = NonUniqueItems.FirstOrDefault(o => o.PrimaryKey == primaryKey); if (indexRecord == null){
indexRecord =
new SingleIndexRecord<T, TIndex>(this, primaryKey, valueToUpdate);NonUniqueItems.Add(indexRecord);
IsDirty =
true;NeedsSorted =
true;}
else{
if (!Common.Compare(indexRecord.Index, valueToUpdate)){
IsDirty =
true;NeedsSorted =
true;indexRecord.Index = valueToUpdate;
indexRecord.LazyValue =
null;}
}
}
/// <summary> /// Delete an item in the index by primary key and set IsDirty to true /// </summary> /// <param name="primaryKey"></param> public override void Delete(long primaryKey){
if (Style == IndexStyle.Unique){
if (UniqueItems.Any(o => o.Value.PrimaryKey == primaryKey)){
TIndex indexValue = UniqueItems.First(o => o.Value.PrimaryKey == primaryKey).Key;
UniqueItems.Remove(indexValue);
IsDirty =
true;}
}
var indexRecord = NonUniqueItems.FirstOrDefault(o => o.PrimaryKey == primaryKey); if (indexRecord != null){
NonUniqueItems.Remove(indexRecord);
IsDirty =
true;NeedsSorted =
true;}
}
/// <summary> /// Get all the primary keys associated with this index in ascending order /// </summary> /// <returns></returns> public override List<long> GetPrimaryKeys(object indexValue){
TIndex indexToFind = (TIndex)
Common.ChangeType(indexValue, typeof(object), typeof(TIndex)); List<long> primaryKeys = (from nonUniqueItem in NonUniqueItems where Common.Compare(nonUniqueItem.Index, indexToFind) select nonUniqueItem.PrimaryKey).ToList(); return primaryKeys;}
/// <summary> /// Get all the primary keys associated with this index in descending order /// </summary> /// <returns></returns> public override List<long> GetAllPrimaryKeysDescending(){
var sortedDescending = NonUniqueItems.OrderByDescending(o => o.Index); return sortedDescending.Select(indexRecord => indexRecord.PrimaryKey).ToList();}
/// <summary> /// Get all the primary keys associated with this index /// </summary> /// <returns></returns> public override List<long> GetAllPrimaryKeys(){
if (NeedsSorted){
SortIndex();
NeedsSorted =
false;}
return NonUniqueItems.Select(indexRecord => indexRecord.PrimaryKey).ToList();}
/// <summary> /// Sort the index by the index value /// </summary> public override void SortIndex(){
NonUniqueItems = NonUniqueItems.OrderBy(o => o.Index).ToList();
}
/// <summary> /// Query for a list of index records /// </summary> /// <returns></returns> public override List<SingleIndexRecord<T, TIndex>> Query(){
return NonUniqueItems;}
/// <summary> /// Get a list of Index Records that match the passed indexValue /// </summary> /// <param name="indexValue"></param> /// <returns></returns> public override List<SingleIndexRecord<T, TIndex>> GetIndexRecordExactMatch(TIndex indexValue){
List<SingleIndexRecord<T, TIndex>> result = new List<SingleIndexRecord<T, TIndex>>(); if (Style == IndexStyle.Unique){
if (UniqueItems.ContainsKey(indexValue)){
result.Add(UniqueItems[indexValue]);
}
}
else{
result.AddRange(NonUniqueItems.Where(o =>
Common.Compare(o.Index, indexValue)));}
return result;}
#endregion
}