How do I use tuple in C# call to _EdgeDBclient.QuerySingleAsync()
Describe the bug
I submitted a question in Discord -> EdgeDb -> edgedb-dotnet on Mon, 1/15/24 but no one has responded as of 1/16/24 14:58 PAC.
I've tried multiple options for using a tuple in an INSERT statement, but I keep getting different warnings returned from EdgeDB. For Visual Studio 2022 C# .NET 7 code $ edgedb --version EdgeDB CLI 4.0.2+b26c502
Reproduction Include the code that is causing the error:
Here is the default.esdl
type Artist {
required artistname: str {
constraint exclusive;
constraint min_len_value(3);
}
othernames: array<str>;
required wikipediapageid: int32;
birthdate: datetime;
familyname: tuple<first: str, middle: str, last: str>;
required multi genres: Genre;
multi labels: MusicCompanyLabel;
required timestamp: datetime;
}
Here is the C# code (below code is the multiple iterations I tried and the EdgeDB errors that were returned):
string familyNameFirst = "";
string familyNameMiddle = "";
string familyNameLast = "";
if (artist.FamilyName != null) {
familyNameFirst = string.Join(", ", artist.FamilyName.Item1);
familyNameMiddle = string.Join(", ", artist.FamilyName.Item2);
familyNameLast = string.Join(", ", artist.FamilyName.Item3);
}
try
{
var result = await _EdgeDBclient.QuerySingleAsync<Artist>(
" INSERT Artist " +
" { artistname := <str>$name, " +
" othernames := <array<str>>$onam, " +
" wikipediapageid := <int32>$wpid, " +
" birthdate := <datetime>$bdat, " +
" familyname := <tuple< first: <str>$fname, middle: <str>$mname, last: <str>$lname >>, " +
" genres := <array<str>>$genr, " +
" labels := <array<str>>$labl, " +
" timestamp := <datetime>$ptst } ",
new
{
name = artist.ArtistName,
onam = otherNamesString,
wpid = artist.WikipediaPageID,
bdat = artist.BirthDate,
fname = familyNameFirst,
mname = familyNameMiddle,
lname = familyNameLast,
genr = genreString,
labl = labelString,
ptst = artist.PageTimeStamp
});
}
catch (EdgeDB.EdgeDBErrorException ex)
{
Console.WriteLine($"{DateTime.Now} BandServer InsertArtistAsync for {artist.ArtistName}, WikiPageID {artist.WikipediaPageID} error from EdgeDB: ( {ex.Message} )");
return false;
}
Here are the various versions I've tried and the error returned:
// " familyname := tuple{ first := <str>$fname, middle := <str>$mname, last := <str>$lname }, " +
// object type or alias 'default::tuple' does not exist
//
// " familyname := { first := <str>$fname, middle := <str>$mname, last := <str>$lname }, " +
// invalid target for property 'familyname' of object type 'default::Artist': 'std::FreeObject'
// (expecting 'tuple<first: std::str, middle: std::str, last: std::str>')
//
// " familyname := tuple<first: <str>$fname, middle: <str>$mname, last: <str>$lname>, " +
// Unexpected ':'
//
// " familyname := tuple<first <str>$fname, middle <str>$mname, last <str>$lname>, " +
// Missing '['
//
// " familyname := { first := <str>$fname, middle := <str>$mname, last := <str>$lname }, " +
// invalid target for property 'familyname' of object type 'default::Artist':
// 'std::FreeObject' (expecting 'tuple<first: std::str, middle: std::str, last: std::str>')
//
// " familyname := { first := <str>$fname, middle := <str>$mname, last := <str>$lname }, " +
//
// " familyname := <tuple< first := $fname, middle := $mname, last := $lname >>, " +
// Unexpected ':='
//
// " familyname := <tuple< first := <str>$fname, middle := <str>$mname, last := <str>$lname >>, " +
// Unexpected ':='
//
//" familyname := <tuple< first : <str>$fname, middle : <str>$mname, last : <str>$lname >>, " +
// Missing keyword 'TYPE'
Expected behavior
Trying to not get and error and INSERT the C# tuple properly into the INSERT statement.
Versions (please complete the following information):
$ dotnet --version8.0.100
Frameworks MicrosoftAspNetCoreApp MicrosoftNETCoreApp Packages EdgeDB.Net.Driver (1.3.0) MicrosoftAspNetCore.OpenApi (7.0.10) Swashbuckle.AspNetCore (6.5.0) System.Net.Http.Json (8.0.0)
- OS: Windows 11
- EdgeDB version:
- EdgeDB CLI version:
-
edgedb-netversion: - .NET version:
Additional context
You could try this:
familyname := <tuple<first:str, middle:str, last:str>>$familyname
You might also consider breaking out familyname as a separate object type. Those can be easier to wrangle than tuples.
Crossposting from Discord:
from just looking at the code you provided, I noted some immediate problems:
-
genresandlabelsare types within the schema, but in the code your casting them to<array<str>>which doesn't insert/select them -
familynamein the code doesn't contain type casts for arguments, resulting in this error:
QueryError: missing a type cast before the parameter
|
1 | INSERT Artist { artistname := <str>$name, othernames := <array<str>>$onam, wikipediapageid := <int32>$wpid, birthdate := <datetime>$bdat, familyname := { first := $fname, middle := $mname, last := $lname }, genres := <array<str>>$genr, labels := <array<str>>$labl, timestamp := <datetime>$ptst }
| ^^^^^^
for this error:
Code: " familyname := { first := <str>$fname, middle := <str>$mname, last := <str>$lname }, " +
Error: invalid target for property 'familyname' of object type 'default::Artist':
'std::FreeObject' (expecting 'tuple<first: std::str, middle: std::str, last: std::str>')
Its telling you that you're trying to cast a free object to a tuple, the { x := y, ...} syntax is a free object in EdgeDB, to specify a tuple you can use (x, y, z, ...) syntax.
fixing these issues seems to work on my end
Hi Quin,
Did you see my question on Discord / edgedb-net about nullable C# class field that is getting runtime error "EdgeDB.MissingCodecException: Cannot find valid codec for System.Nullable`1[System.DateTimeOffset]" ?
Sincerely and Thanks, John Ritz, Software Engineer II 503-309-6411 cell @.*** www.linkedin.com/in/johntritz https://github.com/EncompassingResidential/Band-Tree
On Wed, Jan 17, 2024 at 10:18 AM Quin Lynch @.***> wrote:
Crossposting from Discord:
from just looking at the code you provided, I noted some immediate problems:
- genres and labels are types within the schema, but in the code your casting them to <array
> which doesn't insert/select them - familyname in the code doesn't contain type casts for arguments, resulting in this error:
QueryError: missing a type cast before the parameter | 1 | INSERT Artist { artistname :=
$name, othernames := <array >$onam, wikipediapageid := $wpid, birthdate := $bdat, familyname := { first := $fname, middle := $mname, last := $lname }, genres := <array >$genr, labels := <array >$labl, timestamp := $ptst } | ^^^^^^ for this error:
Code: " familyname := { first :=
$fname, middle := $mname, last := $lname }, " + Error: invalid target for property 'familyname' of object type 'default::Artist': 'std::FreeObject' (expecting 'tuple<first: std::str, middle: std::str, last: std::str>') Its telling you that your trying to cast a free object to a tuple, the { x := y, ...} syntax is a free object in EdgeDB, to specify a tuple you can use (x, y, z, ...) syntax. fixing these issues seems to work on my end
— Reply to this email directly, view it on GitHub https://github.com/edgedb/edgedb-net/issues/75#issuecomment-1896362353, or unsubscribe https://github.com/notifications/unsubscribe-auth/AWOLCDNAVLEGVI5NYECF263YPAIVRAVCNFSM6AAAAABB5SXZJKVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTQOJWGM3DEMZVGM . You are receiving this because you authored the thread.Message ID: @.***>