-
-
Notifications
You must be signed in to change notification settings - Fork 3
QueryBuilder v2 #17
Description
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();