You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Connected.Framework/Connected.Data/Update/UpdateCommandBuilder.cs

82 lines
2.2 KiB

2 years ago
using Connected.Entities.Annotations;
using Connected.Entities.Storage;
using System.Collections.Concurrent;
using System.Reflection;
namespace Connected.Data.Update;
internal sealed class UpdateCommandBuilder : CommandBuilder
{
private static readonly ConcurrentDictionary<string, StorageOperation> _cache;
static UpdateCommandBuilder()
{
_cache = new();
}
private static ConcurrentDictionary<string, StorageOperation> Cache => _cache;
private bool SupportsConcurrency { get; set; }
protected override bool TryGetExisting(out StorageOperation? result)
{
return Cache.TryGetValue(Entity.GetType().FullName, out result);
}
protected override StorageOperation OnBuild()
{
WriteLine($"UPDATE [{Schema.Schema}].[{Schema.Name}] SET");
WriteAssignments();
WriteWhere();
Trim();
Write(';');
var result = new StorageOperation { CommandText = CommandText, Concurrency = SupportsConcurrency ? DataConcurrencyMode.Enabled : DataConcurrencyMode.Disabled };
foreach (var parameter in Parameters)
result.AddParameter(parameter);
Cache.TryAdd(Entity.GetType().FullName, result);
return result;
}
private void WriteAssignments()
{
foreach (var property in Properties)
{
if (property.GetCustomAttribute<PrimaryKeyAttribute>() is not null || IsVersion(property))
{
if (IsVersion(property))
SupportsConcurrency = true;
WhereProperties.Add(property);
continue;
}
var parameter = CreateParameter(property);
WriteLine($"{ColumnName(property)} = {parameter.Name},");
}
Trim();
}
private void WriteWhere()
{
WriteLine(string.Empty);
for (var i = 0; i < WhereProperties.Count; i++)
{
var property = WhereProperties[i];
var parameter = CreateParameter(property);
if (i == 0)
WriteLine($" WHERE {ColumnName(property)} = {parameter.Name}");
else
WriteLine($" AND {ColumnName(property)} = {parameter.Name}");
}
}
}