Skip to content

Instantly share code, notes, and snippets.

@nickalbrecht
Created November 24, 2023 19:18
Show Gist options
  • Save nickalbrecht/d3d56b7936024222ca9f041d174d3bd3 to your computer and use it in GitHub Desktop.
Save nickalbrecht/d3d56b7936024222ca9f041d174d3bd3 to your computer and use it in GitHub Desktop.
An extension method for use on a FormattableString to allow combining them, but keeping the output as a FormattableString, not string. I added this to allow passing it to EFCore, and let it handle parameterizing the command. Otherwise you have to do this yourself and call the RawSql variant of methods and pass in the parameters yourself. I'm not…
[GeneratedRegex(@"\{(\d+)\}")]
private static partial Regex FormattableStringArgumentRegex();
/// <summary>
/// Extension method for combining two <see cref="FormattableString"/>, and returning a new <see cref="FormattableString"/> with the combined arguments and format
/// </summary>
/// <remarks>Originally added to facilitate dynamically building up querystrings that EFCore would take and excute</remarks>
public static FormattableString Combine(this FormattableString baseFormattableString, FormattableString addingFormattableString)
{
var regex = FormattableStringArgumentRegex();
object?[] newArguments = new object[baseFormattableString.ArgumentCount + addingFormattableString.ArgumentCount];
baseFormattableString.GetArguments().CopyTo(newArguments, 0);
addingFormattableString.GetArguments().CopyTo(newArguments, baseFormattableString.ArgumentCount);
return System.Runtime.CompilerServices.FormattableStringFactory.Create(
baseFormattableString.Format + regex.Replace(addingFormattableString.Format, match => {
// Convert captured index to an integer and add the offset
if (int.TryParse(match.Groups[1].Value, out var index)) {
return $"{{{index + baseFormattableString.ArgumentCount}}}";
}
return match.Value; // If not a valid number, return the original text
}), newArguments);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment