![]() |
VOOZH | about |
Supabase is migrating its packages to match the Nuget naming conventions.
dotnet add package postgrest-csharp --version 3.5.1
NuGet\Install-Package postgrest-csharp -Version 3.5.1
<PackageReference Include="postgrest-csharp" Version="3.5.1" />
<PackageVersion Include="postgrest-csharp" Version="3.5.1" />Directory.Packages.props
<PackageReference Include="postgrest-csharp" />Project file
paket add postgrest-csharp --version 3.5.1
#r "nuget: postgrest-csharp, 3.5.1"
#:package postgrest-csharp@3.5.1
#addin nuget:?package=postgrest-csharp&version=3.5.1Install as a Cake Addin
#tool nuget:?package=postgrest-csharp&version=3.5.1Install as a Cake Tool
<p align="center"> <img width="300" src=".github/logo.png"/> </p>
<p align="center"> <img src="https://github.com/supabase/postgrest-csharp/workflows/Build%20And%20Test/badge.svg"/> <a href="https://www.nuget.org/packages/postgrest-csharp/"> <img src="https://img.shields.io/badge/dynamic/json?color=green&label=Nuget%20Release&query=data[0].version&url=https%3A%2F%2Fazuresearch-usnc.nuget.org%2Fquery%3Fq%3Dpackageid%3Apostgrest-csharp"/> </a> </p>
await client.Table<Movie>()
.Select(x => new object[] { x.Id, x.Name, x.Tags, x.ReleaseDate })
.Where(x => x.Tags.Contains("Action") || x.Tags.Contains("Adventure"))
.Order(x => x.ReleaseDate, Ordering.Descending)
.Get();
await client.Table<Movie>()
.Set(x => x.WatchedAt, DateTime.Now)
.Where(x => x.Id == "11111-22222-33333-44444")
// Or .Filter(x => x.Id, Operator.Equals, "11111-22222-33333-44444")
.Update();
Documentation can be found here.
Postgrest-csharp is written primarily as a helper library for supabase/supabase-csharp, however, it should be easy enough to use outside of the supabase ecosystem.
The bulk of this library is a translation and c-sharp-ification of the supabase/postgrest-js library.
Postgrest-csharp is heavily dependent on Models deriving from BaseModel. To interact with the API, one must have the
associated
model specified.
To use this library on the Supabase Hosted service but separately from the supabase-csharp, you'll need to specify
your url and public key like so:
var auth = new Supabase.Gotrue.Client(new ClientOptions<Session>
{
Url = "https://PROJECT_ID.supabase.co/auth/v1",
Headers = new Dictionary<string, string>
{
{ "apikey", SUPABASE_PUBLIC_KEY },
{ "Authorization", $"Bearer {SUPABASE_USER_TOKEN}" }
}
})
Leverage Table,PrimaryKey, and Column attributes to specify names of classes/properties that are different from
their C# Versions.
[Table("messages")]
public class Message : BaseModel
{
[PrimaryKey("id")]
public int Id { get; set; }
[Column("username")]
public string UserName { get; set; }
[Column("channel_id")]
public int ChannelId { get; set; }
public override bool Equals(object obj)
{
return obj is Message message &&
Id == message.Id;
}
public override int GetHashCode()
{
return HashCode.Combine(Id);
}
}
Utilizing the client is then just a matter of instantiating it and specifying the Model one is working with.
void Initialize()
{
var client = new Client("http://localhost:3000");
// Get All Messages
var response = await client.Table<Message>().Get();
List<Message> models = response.Models;
// Insert
var newMessage = new Message { UserName = "acupofjose", ChannelId = 1 };
await client.Table<Message>().Insert();
// Update
var model = response.Models.First();
model.UserName = "elrhomariyounes";
await model.Update();
// Delete
await response.Models.Last().Delete();
}
The Postgrest server does introspection on relationships between tables and supports returning query data from tables with these included. Foreign key constrains are required for postgrest to detect these relationships.
This library implements the attribute, Reference to specify on a model when a relationship should be included in a
query.
Given the following schema:
We can define the following models:
[Table("movie")]
public class Movie : BaseModel
{
[PrimaryKey("id")]
public int Id { get; set; }
[Column("name")]
public string Name { get; set; }
[Reference(typeof(Person))]
public List<Person> Persons { get; set; }
[Column("created_at")]
public DateTime CreatedAt { get; set; }
}
[Table("person")]
public class Person : BaseModel
{
[PrimaryKey("id")]
public int Id { get; set; }
[Column("first_name")]
public string FirstName { get; set; }
[Column("last_name")]
public string LastName { get; set; }
[Reference(typeof(Profile))]
public Profile Profile { get; set; }
[Column("created_at")]
public DateTime CreatedAt { get; set; }
}
[Table("profile")]
public class Profile : BaseModel
{
[Column("email")]
public string Email { get; set; }
}
Note that each related model should inherit BaseModel and specify its Table and Column attributes as usual.
The Reference Attribute by default will include the referenced model in all GET queries on the table (this can be
disabled
in its constructor).
As such, a query on the Movie model (given the above) would return something like:
[
{
id: 1,
created_at: "2022-08-20T00:29:45.400188",
name: "Top Gun: Maverick",
person: [
{
id: 1,
created_at: "2022-08-20T00:30:02.120528",
first_name: "Tom",
last_name: "Cruise",
profile: {
profile_id: 1,
email: "tom.cruise@supabase.io",
created_at: "2022-08-20T00:30:33.72443"
}
},
{
id: 3,
created_at: "2022-08-20T00:30:33.72443",
first_name: "Bob",
last_name: "Saggett",
profile: {
profile_id: 3,
email: "bob.saggett@supabase.io",
created_at: "2022-08-20T00:30:33.72443"
}
}
]
},
// ...
]
Circular relations can be added between models, however, circular relations should only be parsed one level deep for
models. For example, given the
models here,
a raw response would look like the following (note that the Person object returns the root Movie and
the Person->Profile returns its root Person object).
If desired, this can be avoided by making specific join models that do not have the circular references.
[
{
"id": "68722a22-6a6b-4410-a955-b4eb8ca7953f",
"created_at": "0001-01-01T05:51:00",
"name": "Supabase in Action",
"person": [
{
"id": "6aa849d8-dd09-4932-bc6f-6fe3b585e87f",
"first_name": "John",
"last_name": "Doe",
"created_at": "0001-01-01T05:51:00",
"movie": [
{
"id": "68722a22-6a6b-4410-a955-b4eb8ca7953f",
"name": "Supabase in Action",
"created_at": "0001-01-01T05:51:00"
}
],
"profile": {
"person_id": "6aa849d8-dd09-4932-bc6f-6fe3b585e87f",
"email": "john.doe@email.com",
"created_at": "0001-01-01T05:51:00",
"person": {
"id": "6aa849d8-dd09-4932-bc6f-6fe3b585e87f",
"first_name": "John",
"last_name": "Doe",
"created_at": "0001-01-01T05:51:00"
}
}
},
{
"id": "07abc67f-bf7d-4865-b2c0-76013dc2811f",
"first_name": "Jane",
"last_name": "Buck",
"created_at": "0001-01-01T05:51:00",
"movie": [
{
"id": "68722a22-6a6b-4410-a955-b4eb8ca7953f",
"name": "Supabase in Action",
"created_at": "0001-01-01T05:51:00"
}
],
"profile": {
"person_id": "07abc67f-bf7d-4865-b2c0-76013dc2811f",
"email": "jane.buck@email.com",
"created_at": "0001-01-01T05:51:00",
"person": {
"id": "07abc67f-bf7d-4865-b2c0-76013dc2811f",
"first_name": "Jane",
"last_name": "Buck",
"created_at": "0001-01-01T05:51:00"
}
}
}
]
}
]
By default relations expect to be used as top level filters on a query. If following the models above, this would
mean that a Movie with no Person relations on it would not return on a query unless the Relation
has useInnerJoin set to false:
The following model would return any movie, even if there are no Person models associated with it:
[Table("movie")]
public class Movie : BaseModel
{
[PrimaryKey("id")]
public string Id { get; set; }
[Column("name")]
public string? Name { get; set; }
[Reference(typeof(Person), useInnerJoin: false)]
public List<Person> People { get; set; } = new();
}
Further Notes:
Relation attribute uses reflection to only select the attributes specified on the Class Model (i.e.
the Profile model has a property only for email, only the property will be requested in the query).int4range, int8rangenumrangetsrange, tstzrange, daterangeBaseModel to derive from| <img src="https://github.com/acupofjose.png" width="150" height="150"> | <img src="https://github.com/elrhomariyounes.png" width="150" height="150"> |
|---|---|
| acupofjose | elrhomariyounes |
We are more than happy to have contributions! Please submit a PR.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 net5.0 was computed. net5.0-windows net5.0-windows was computed. net6.0 net6.0 was computed. net6.0-android net6.0-android was computed. net6.0-ios net6.0-ios was computed. net6.0-maccatalyst net6.0-maccatalyst was computed. net6.0-macos net6.0-macos was computed. net6.0-tvos net6.0-tvos was computed. net6.0-windows net6.0-windows was computed. net7.0 net7.0 was computed. net7.0-android net7.0-android was computed. net7.0-ios net7.0-ios was computed. net7.0-maccatalyst net7.0-maccatalyst was computed. net7.0-macos net7.0-macos was computed. net7.0-tvos net7.0-tvos was computed. net7.0-windows net7.0-windows was computed. net8.0 net8.0 was computed. net8.0-android net8.0-android was computed. net8.0-browser net8.0-browser was computed. net8.0-ios net8.0-ios was computed. net8.0-maccatalyst net8.0-maccatalyst was computed. net8.0-macos net8.0-macos was computed. net8.0-tvos net8.0-tvos was computed. net8.0-windows net8.0-windows was computed. net9.0 net9.0 was computed. net9.0-android net9.0-android was computed. net9.0-browser net9.0-browser was computed. net9.0-ios net9.0-ios was computed. net9.0-maccatalyst net9.0-maccatalyst was computed. net9.0-macos net9.0-macos was computed. net9.0-tvos net9.0-tvos was computed. net9.0-windows net9.0-windows was computed. net10.0 net10.0 was computed. net10.0-android net10.0-android was computed. net10.0-browser net10.0-browser was computed. net10.0-ios net10.0-ios was computed. net10.0-maccatalyst net10.0-maccatalyst was computed. net10.0-macos net10.0-macos was computed. net10.0-tvos net10.0-tvos was computed. net10.0-windows net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 netcoreapp2.0 was computed. netcoreapp2.1 netcoreapp2.1 was computed. netcoreapp2.2 netcoreapp2.2 was computed. netcoreapp3.0 netcoreapp3.0 was computed. netcoreapp3.1 netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 netstandard2.0 is compatible. netstandard2.1 netstandard2.1 was computed. |
| .NET Framework | net461 net461 was computed. net462 net462 was computed. net463 net463 was computed. net47 net47 was computed. net471 net471 was computed. net472 net472 was computed. net48 net48 was computed. net481 net481 was computed. |
| MonoAndroid | monoandroid monoandroid was computed. |
| MonoMac | monomac monomac was computed. |
| MonoTouch | monotouch monotouch was computed. |
| Tizen | tizen40 tizen40 was computed. tizen60 tizen60 was computed. |
| Xamarin.iOS | xamarinios xamarinios was computed. |
| Xamarin.Mac | xamarinmac xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos xamarinwatchos was computed. |
Showing the top 2 NuGet packages that depend on postgrest-csharp:
| Package | Downloads |
|---|---|
|
supabase-csharp
A C# implementation of the Supabase client |
|
|
realtime-csharp
Realtime-csharp is written as a client library for supabase/realtime. |
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated | |
|---|---|---|---|
| 3.5.1 | 123,476 | 3/15/2024 | 3.5.1 is deprecated. |
| 3.5.0 | 12,789 | 1/14/2024 | |
| 3.4.1 | 13,243 | 1/8/2024 | |
| 3.4.0 | 3,507 | 1/3/2024 | |
| 3.3.0 | 3,539 | 11/29/2023 | |
| 3.2.10 | 15,343 | 11/13/2023 | |
| 3.2.9 | 7,405 | 10/9/2023 | |
| 3.2.8 | 307 | 10/9/2023 | |
| 3.2.7 | 11,376 | 9/15/2023 | |
| 3.2.6 | 331 | 9/5/2023 | |
| 3.2.5 | 8,704 | 7/13/2023 | |
| 3.2.4 | 4,918 | 6/29/2023 | |
| 3.2.3 | 791 | 6/25/2023 | |
| 3.2.2 | 80,158 | 6/10/2023 | |
| 3.2.1 | 406 | 6/10/2023 | |
| 3.2.0 | 4,992 | 5/24/2023 | |
| 3.1.3 | 27,734 | 1/31/2023 | |
| 3.1.2 | 1,186 | 1/27/2023 | |
| 3.1.1 | 1,622 | 1/17/2023 | |
| 3.1.0 | 821 | 1/16/2023 |