LabelKit.EFCore.Pomelo.MySql
3.0.0
dotnet add package LabelKit.EFCore.Pomelo.MySql --version 3.0.0
NuGet\Install-Package LabelKit.EFCore.Pomelo.MySql -Version 3.0.0
<PackageReference Include="LabelKit.EFCore.Pomelo.MySql" Version="3.0.0" />
paket add LabelKit.EFCore.Pomelo.MySql --version 3.0.0
#r "nuget: LabelKit.EFCore.Pomelo.MySql, 3.0.0"
// Install LabelKit.EFCore.Pomelo.MySql as a Cake Addin
#addin nuget:?package=LabelKit.EFCore.Pomelo.MySql&version=3.0.0
// Install LabelKit.EFCore.Pomelo.MySql as a Cake Tool
#tool nuget:?package=LabelKit.EFCore.Pomelo.MySql&version=3.0.0
LabelKit
LabelKit is a .NET toolkit for parsing kubernetes-like label-selectors and using them to build filters, including query-expressions for EFCore (PostgreSQL, MySql, SqlServer, Sqlite). Labels are name/value pairs that can be represented as dictionaries (name->value) or simple string collections (name+delimiter+value).
Packages
The majority of packages support netstandard2.0.
The following NuGet packages are provided:
- LabelKit
- You need to reference structured label-selectors.
- LabelKit.Parser
- You need to parse raw label-selectors.
- LabelKit.Expressions
- You need to build expressions and filter queries. See here.
- LabelKit.EFCore.PostgreSQL
- You need to filter EFCore-PostgreSQL queries. See here.
- LabelKit.EFCore.Pomelo.MySql
- You need to filter EFCore-MySql queries. See here.
Examples
EFCore PostgreSQL:
public class Entity
{
// Stored as JSONB
public Dictionary<string, string> Labels { get; set; }
}
dotnet add package LabelKit.Parser
LabelKit.Parser offers a default parser built with Pidgin.
The parser is able to parse raw label-selectors adhering to the kubernetes syntax.
using LabelKit;
var selector = LabelSelectorParser.Parse(
"label1 = value, label2 = value, label3 in (value1, value2)");
dotnet add package LabelKit.EFCore.PostgreSQL
var expressionBuilder = NpgsqlLabelSelectorExpressionBuilders.Jsonb<Dictionary<string, string>>();
var entities = await dbContext.Set<Entity>()
.MatchLabels(e => e.Labels, selector, expressionBuilder)
.ToListAsync();
Executed SQL:
-- @__json_1='{"label1":"value","label2":"value"}' (DbType = Object)
-- @__Format_2='{"label3":"value1"}' (DbType = Object)
-- @__Format_3='{"label3":"value2"}' (DbType = Object)
SELECT t."Id", t."Labels"
FROM "TestEntity" AS t
WHERE t."Labels" @> @__json_1 AND (t."Labels" @> @__Format_2 OR t."Labels" @> @__Format_3)
Label-Selectors
Label-selectors can be easily created and extended...
var selector = LabelSelector.New()
.Match("label1").Exact("value")
.Match("label2").Not("value")
.Match("label3").In("value1", "value2")
.Match("label4").NotIn("value1", "value2")
.Match("label5").Exists()
.Match("label6").NotExists();
They can be merged...
var selector1 = LabelSelector.New()
.Match("label1").Exact("value");
var selector2 = LabelSelector.New()
.Match("label2").Exact("value");
// Contains a fully copy of all expressions
var merged = selector1.Merge(selector2);
// You can merge an arbitrary number of selectors
merged = LabelSelector.Merge(selector1, selector2, ...);
They can be rendered...
// label1 = value, label2 = value
merged.ToString();
Matching Labels Offline
You can also use label-selectors offline without any database interaction.
dotnet add package LabelKit
var selector = LabelSelector.New()
.Match("label1").Exact("value")
.Match("label2").Exact("value");
string[] labels = [ "label1:value", "label2:value" ];
// Default delimiter is ':'
// -> true
var doesMatch = selector.Matches(labels);
The same can be done with dictionary-like labels:
var selector = LabelSelector.New()
.Match("label1").Exact("value")
.Match("label2").Exact("value");
var labels = new Dictionary<string, string()
{
["label1"] = "value",
["label2"] = "value"
};
// -> true
var doesMatch = selector.Matches(labels);
[!TIP]
Any component implementing ILabelSelector (meaning it can provide a collection of selector-expressions) can be used to match offline.
Expressions (EFCore)
LabelKit supports infrastructure for building expression-trees that can be used to filter IQueryables. Components implementing ILabelSelectorExpressionBuilder are responsible for creating Expressions from label-selectors. Different expression-builders are needed for different scenarios.
Example: If your labels are stored as JSONB (PostgreSQL), the resulting SQL query has to be vastly different from if they were stored as an array. Therefore, you need a different expression.
Supported EFCore Providers
- PostgreSQL (>=5.0.5)
- Supports labels stored as JSONB ("name": "value")
- Supports labels stored as primitive-collection of strings ("name{separator}value").
- MySql (>=3.2.0)
- Supports labels stored as JSON ("name": "value")
- Supports labels stored as primitive-collection of strings ("name{separator}value").
- Disabled by default in the provider due to this issue here.
- SqlServer (>=8.0.0)
- Supports labels stored as primitive-collection of strings ("name{separator}value").
- Sqlite (>=8.0.0)
- Supports labels stored as primitive-collection of strings ("name{separator}value").
- Any other EFCore provider supporting primitive-collections
- Supports labels stored as primitive-collection of strings ("name{separator}value").
Provided Expression-Builders
NpgsqlJsonbLabelSelectorExpressionBuilder
(NpgsqlLabelSelectorExpressionBuilders.Jsonb()
)- Builds expression specifically suited for PostgreSQL JSONB columns.
MySqlJsonLabelSelectorExpressionBuilder
(MySqlLabelSelectorExpressionBuilders.Json()
)- Builds expression specifically suited for MySql JSON columns.
CollectionLabelSelectorExpressionBuilder
(LabelSelectorExpressionBuilders.Collection()
)- Builds generic expression suitable for any collection of strings.
- Supported by PostgreSQL, SqlServer, Sqlite (and MySql).
- Available in package
LabelKit.Expressions
.
[!IMPORTANT]
CollectionLabelSelectorExpressionBuilder
produces expressions that should be translatable to SQL by EFCore providers supporting primitive-collections. However, you should also be able to use those expressions offline (compiled).
Filter IQueryables
dotnet add package LabelKit.Expressions
using LabelKit;
var expressionBuilder = LabelSelectorExpressionBuilders.Collection<string[]>();
// e => e.Labels is an expression representing the labels to match.
// You can also mark your entity as ILabelledEntity to avoid having to specify this every time.
var entities = await dbContext.Set<Entity>()
.MatchLabels(e => e.Labels,
selector => selector
.Match("label1").Exact("value")
.Match("label2").Exact("value")
, expressionBuilder)
.ToListAsync();
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
.NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- LabelKit.Expressions (>= 0.1.0)
- LinqKit.Core (>= 1.2.0)
- Pomelo.EntityFrameworkCore.MySql (>= 3.2.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
3.0.0 | 84 | 5/5/2024 |
3.0.0-alpha.1003 | 57 | 4/30/2024 |