Last active
September 11, 2024 12:24
-
-
Save GW-FUB/d7cfa866023e82f6538bbf83047c331e to your computer and use it in GitHub Desktop.
LiteDB Replace With CUD
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class DBContext | |
{ | |
private LiteDatabase _userDB; | |
public static DBContext Instance { get; } = new DBContext(DefaultDatabaseFolderPath); | |
... | |
string userDataDBFilePath = Path.Combine(DatabaseFolderPath, "UserData.lite"); | |
_userDB = new LiteDatabase(GetConnectionString(userDataDBFilePath)) | |
{ | |
UtcDate = true | |
}; | |
... | |
private static ConnectionString GetConnectionString(string databasePath) => new ConnectionString | |
{ | |
Filename = databasePath, | |
Upgrade = true, | |
}; | |
... | |
/// <summary> | |
/// Gets a collection with the name of the calling property. | |
/// </summary> | |
/// <remarks> Accesses the user database. May only be called when logged in. </remarks> | |
/// <exception cref="NullReferenceException"> When no user is logged in. </exception> | |
public ILiteCollection<T> GetNamedCollection<T>([CallerMemberName] string name = null) where T : new() => _userDB.GetCollection<T>(name); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public static class DBContextExtensions | |
{ | |
... | |
public static ILiteCollection<MyValueDto> MyValueDtos(this DBContext context) | |
{ | |
var collection = context.GetNamedCollection<MyValueDto>(); | |
collection.EnsureIndex(x => x.Value); | |
collection.EnsureIndex(x => x.Table); | |
return collection; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Get values by extension collection | |
var existing = DBContext.Instance.MyValueDtos().FindAll().ToList(); | |
var current = newItems.ToList(); | |
var (creates, updates, deletes) = existing.GetCUD(current, x => x.Id); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/// <summary> | |
/// Compares a source sequence to another by id and returns the creates, updates and deletes that are necessary for the source sequence.<br/> | |
/// <br/> | |
/// Creates: Missing in the source. Updates: Exist in both. Deletes: Just present in the source. | |
/// </summary> | |
/// <typeparam name="TId"> The type of the id to compare. </typeparam> | |
/// <param name="source"> The source sequence. Contains the currently present items. </param> | |
/// <param name="compare"> The compare sequence. Contains the currently available items. The source sequence should get modified to include the same items. </param> | |
/// <returns> The necessary creates, updates and deletes for the source sequence. </returns> | |
public static (IEnumerable<T> creates, IEnumerable<T> updates, IEnumerable<T> deletes) GetCUD<T, TId>(this IEnumerable<T> source, IEnumerable<T> compare, Func<T, TId> getId) | |
{ | |
List<(T item, TId id)> sourceItems = source.Select(x => (x, getId(x))).ToList(); | |
List<(T item, TId id)> compareItems = compare.Select(x => (x, getId(x))).ToList(); | |
var sourceIds = new HashSet<TId>(sourceItems.Select(x => x.id)); | |
var compareIds = new HashSet<TId>(compareItems.Select(x => x.id)); | |
// Exists only in the second => Create | |
var createIds = compareIds.Except(sourceIds); | |
var creates = compareItems.Where(x => createIds.Contains(x.id)).Select(x => x.item); | |
// Exists in both => Update | |
var updateIds = sourceIds.Intersect(compareIds); | |
var updates = updateIds.Select(updateId => compareItems.Find(item => item.id.Equals(updateId)).item); | |
// Exists only in the first => Delete | |
var deleteIds = sourceIds.Except(compareIds); | |
var deletes = sourceItems.Where(x => deleteIds.Contains(x.id)).Select(x => x.item); | |
return (creates, updates, deletes); | |
} | |
/// <summary> | |
/// Compares a source sequence to another by id and returns the creates, updates and deletes that are necessary for the source sequence.<br/> | |
/// <br/> | |
/// Creates: Missing in the source. Updates: Exist in both. Deletes: Just present in the source. | |
/// </summary> | |
/// <typeparam name="TId"> The type of the id to compare. </typeparam> | |
/// <param name="source"> The source sequence. Contains the currently present items. </param> | |
/// <param name="compare"> The compare sequence. Contains the currently available items. The source sequence should get modified to include the same items. </param> | |
/// <returns> The necessary creates, updates and deletes for the source sequence. </returns> | |
public static (IEnumerable<T2> creates, IEnumerable<(T, T2)> updates, IEnumerable<T> deletes) GetCUD<T, T2, TId>(this IEnumerable<T> source, Func<T, TId> getIdOfSource, IEnumerable<T2> compare, Func<T2, TId> getIdOfCompare) | |
{ | |
List<(T item, TId id)> sourceItems = source.Select(x => (x, getIdOfSource(x))).ToList(); | |
List<(T2 item, TId id)> compareItems = compare.Select(x => (x, getIdOfCompare(x))).ToList(); | |
var sourceIds = new HashSet<TId>(sourceItems.Select(x => x.id).Distinct()); | |
var compareIds = new HashSet<TId>(compareItems.Select(x => x.id).Distinct()); | |
// Exists only in the second => Create | |
var createIds = compareIds.Except(sourceIds); | |
var creates = compareItems.Where(x => createIds.Contains(x.id)).Select(x => x.item); | |
// Exists in both => Update | |
var updateIds = sourceIds.Intersect(compareIds); | |
var updates = updateIds.Select(updateId => (sourceItems.Find(item => item.id.Equals(updateId)).item, compareItems.Find(item => item.id.Equals(updateId)).item)); | |
// Exists only in the first => Delete | |
var deleteIds = sourceIds.Except(compareIds); | |
var deletes = sourceItems.Where(x => deleteIds.Contains(x.id)).Select(x => x.item); | |
return (creates, updates, deletes); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public static void Replace<T>(this ILiteCollection<T> collection, IEnumerable<T> items) | |
{ | |
var mapper = BsonMapper.Global; | |
var entityMapper = collection.EntityMapper; | |
var idField = entityMapper.Id; | |
var idType = idField.DataType; | |
IEnumerable<(BsonValue id, T element)> existingIds = collection.FindAll().Select(x => (GetBsonValue(x), x)); | |
IEnumerable<(BsonValue id, T element)> currentIds = items.Select(x => (GetBsonValue(x), x)); | |
var (creates, updates, deletes) = existingIds.GetCUD(currentIds, x => x.id); | |
foreach (var (id, element) in deletes.ToList()) | |
{ | |
collection.Delete(id); | |
} | |
foreach (var (id, element) in updates.ToList()) | |
{ | |
collection.Update(element); | |
} | |
foreach (var (id, element) in creates.ToList()) | |
{ | |
collection.Insert(element); | |
} | |
BsonValue GetBsonValue(T item) | |
{ | |
var value = idField.Getter(item); | |
return mapper.Serialize(idType, value); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment