Reading rows
A query runs when you call one of these. Which one you pick says how many rows you expect back.
All
Every matching row, as []*T. No matches means an empty result, not an error.
users, err := db.Users.Where(ant.Gt(&U.Age, 18)).All(ctx)
if err != nil {
return err
}
for _, user := range users {
fmt.Println(user.Name)
}
First
One row, or ant.ErrNotFound.
oldest, err := db.Users.OrderByDesc(&U.Age).First(ctx)
if errors.Is(err, ant.ErrNotFound) {
return nil
}
Single
Exactly one row. You get ant.ErrNotFound if there's none, and ant.ErrMultipleRows if there's more, which suits looking up something that should be unique.
user, err := db.Users.Where(ant.Eq(&U.Email, "ada@example.com")).Single(ctx)
Find
One row by primary key, or ant.ErrNotFound. For a composite key, use FindKey.
user, err := db.Users.Find(ctx, id)
Each
Streams rows one at a time, for results too big to hold in memory. It's a Go iterator, and break releases the connection.
for user, err := range db.Users.OrderBy(&U.Name).Each(ctx) {
if err != nil {
return err
}
fmt.Println(user.Name)
}
If the query has a mistake, it arrives as the only item. Each yields values, so its rows aren't tracked, and it refuses Include because rows are still streaming in. Use Chunk for that.
Counting and checking
n, err := db.Users.Where(ant.Gt(&U.Age, 18)).Count(ctx)
found, err := db.Users.Where(ant.Eq(&U.Name, "Ada")).Exists(ctx)
missing, err := db.Users.Where(ant.Eq(&U.Name, "Ada")).DoesNotExist(ctx)
Count honors Limit, Offset, and Distinct.
One column
ant.Pluck reads a single column into a slice of its type. With a pointer column, NULLs stay nil.
names, err := ant.Pluck(ctx, db.Users.OrderBy(&U.Name), &U.Name)
bios, err := ant.Pluck(ctx, db.Users.Where(), &U.Bio)
Part of a row
Column and Omit load only some columns. The other fields keep their zero value, which is why these rows are never tracked: they can't be saved by mistake.
names, err := db.Users.Column(&U.ID).Column(&U.Name).All(ctx)
small, err := db.Users.Omit(&U.Bio).All(ctx)
Distinct
ages, err := db.Users.Column(&U.Age).Distinct().All(ctx)
Skipping the tracker
Results are tracked by default, so SaveChanges can see what you change. For reads you won't change, NoTracking skips the snapshot.
users, err := db.Users.NoTracking().Where(ant.Gt(&U.Age, 18)).All(ctx)
NoTrackingResolved skips it too, but still gives each row a single instance, which helps when a read returns the same parent many times.
See it tested: tests/features/querying