Skip to content
This repository was archived by the owner on Oct 6, 2022. It is now read-only.
This repository was archived by the owner on Oct 6, 2022. It is now read-only.

QueryBuilder v2 #17

@quinchs

Description

@quinchs

EdgeDB.Net QueryBuilder V2

Goals

  • EFCore-like flow for database access.
  • No runtime assemblies
  • Full edgeql support
  • Abstraction but not to the point where query options cant be explicitly changed

Main structures for DX

QueryBuilder class

The query builder class is for building sub queries, can also be executed by passing a client into the execute function.

QueryableCollection<TType>

Returned from the client.GetCollection<> method, this class is the main class users will use to query objects. It’s lifetime is per query and should not act as a singleton.

QueryContext

The context passed into queries to access any globals within queries.

Return structure

Each query function returns a specific interface that limits the following query options, ex: Insert can only be followed by UnlessConflictOn

User flow

Users will get a ‘collection’ like object to work with for preforming queries, similar to DbSet in efcore.

var collection = _edgedb.GetCollection<TType>();

Select statements

Select statement can be explicit or implicit, the reason for explicit is to provide shapes while implicit select the default shape of the object

Implicit

var result = await collection.Filter(x => x.SomeProperty == "SomeValue").ExecuteAsync();

Explicit

var result = await collection.Select(() => new 
{
    propA = true,
    propB = true,
    computed = 123 * 456
}).ExecuteAsync();

The idea for expressions in selects is to allow the qb to introspect the select to allow computed properties.

Insert statements

Insert statements are pretty simple, take in a type and generate the insert query for it.

var collection = edgedb.GetCollection<Person>();
var person = await collection.Insert(new Person() { Name = "John Doe" }).ExecuteAsync();

The insert statement will also by default select the newly inserted object out, the generated query looks like this:

with RANDOMNAME := insert Person { name := <str>$GOMVWRK }
select RANDOMNAME { name }

With statements and Query Globals

With statements are implicit as they only serve to add global query variables, the syntax is as follows:

collection.With("name", "value");

With statements can be stacked, they also support sub queries:

collection.With("name", QueryBuilder.Insert(..));

Accessing query globals in queries

Query globals can be accessed with the query context passed into any query function

var collection = edgedb.GetCollection<Person>();

collection
    .With("name", "John Smith")
    .With("friend", QueryBuilder.Filter<Person>(x => x.Name == "Jack Doe"));

collection.Insert(ctx => new Person()
{
    Name = ctx.Global<string>("name"),
    BestFriend = ctx.Global<Person>("friend")
});

await collection.ExecuteAsync();

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions