GithubHelp home page GithubHelp logo

Comments (16)

roji avatar roji commented on June 15, 2024 1

@zN3utr4l which exact version of EF and EFCore.PG are you using? Can you make sure that it's the latest patch version for both?

If you're still getting the error, please post a minimal, runnable console program that shows the error happening - I can investigate at that point.

from efcore.pg.

roji avatar roji commented on June 15, 2024 1

@zN3utr4l thanks, I finally managed to "Capacity: 4" in the database, which is definitely a bug; I'm pretty sure that List<List<X>> isn't currently supported by EF - but even if that's the case, it should be erroring in validation and not saving "Capacity: 4" to the database. I've opened dotnet/efcore#33913 on the EF side to discuss this, and will close this issue here (as this isn't a PostgreSQL-specific problem) - please follow that issue.

A couple comments on the above issue... First, see dotnet/efcore#33913 for what a minimal repro looks like - it's a console program, with just the lines needed to actually reproduce the issue; the repros you've been providing consist of projects with many files, needlessly using ASP.NET (rather than a simple console program), etc. That's fine, but open source maintainers (like myself) need to go through dozens of issues each day, and the more minimal/tight the repo, the more you're helping us understand what's going on.

In addition, this issue started with a non-reproducible "Invalid token type: 'StartArray'", continued to an unrelated question on the ToString() representation with Castle.Proxies, and finally ended up with the actual issue. Again, that's absolutely OK - but it doesn't help me remember what this issue is about when I revisit it and re-read it from the top. I advise making an effort to keep issues very focused, dealing with a single problem, and containing a small, completely clear code repro; that saves everyone's time and helps maintainers manage their repos.

from efcore.pg.

zN3utr4l avatar zN3utr4l commented on June 15, 2024

Minimal Repo: https://github.com/zN3utr4l/ErrorNpgsql-ListOfLists-Jsonb/tree/main

Yes, I'm using the latest version, specifically these are the dependencies:

<ItemGroup>
  <PackageReference Include="EFCore.NamingConventions" Version="8.0.3" />
  <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="8.0.5" />
  <PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.5">
    <PrivateAssets>all</PrivateAssets>
    <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    <TreatAsUsed>true</TreatAsUsed>
  </PackageReference>
  <PackageReference Include="Microsoft.EntityFrameworkCore.Proxies" Version="8.0.5" />
  <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.5">
    <PrivateAssets>all</PrivateAssets>
    <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
    <TreatAsUsed>true</TreatAsUsed>
  </PackageReference>
  <PackageReference Include="NLog.Database" Version="5.3.2">
    <TreatAsUsed>true</TreatAsUsed>
  </PackageReference>
  <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="8.0.4" />
</ItemGroup>

from efcore.pg.

roji avatar roji commented on June 15, 2024

I ran your code, accessed the endpoint (/error-jsonb) and got an empty array, as expected (the database is empty). I then added the following to the handler:

context.Add(new MyEntity
{
    JsonbFields = [
        [new() { Key = "key1", Value = "value1"}],
        [new() { Key = "key2", Value = "value2"}]
    ]
});
context.SaveChanges();

After accessing the endpoint again, I get the expected output:

[{"id":1,"jsonbFields":[[{"key":"key1","value":"value1"}],[{"key":"key2","value":"value2"}]]}]

It's very likely to you have some data in your database that's somehow malformed and causing this; it's possible the EF's JSON deserializer (which is used when you map via owned entities) is stricter in some way, which that data used to work but doesn't any more.

Long story short, you'll have to track down the offending column data. If it looks like correct JSON, please post it here so I can investigate.

from efcore.pg.

zN3utr4l avatar zN3utr4l commented on June 15, 2024

This is what comes back if it adds what you did.

image

app.MapGet("/error-jsonb", ([FromServices] CustomDbContext context) =>
{
    context.Add(new MyEntity
    {
        JsonbFields = [
        [new() { Key = "key1", Value = "value1"}],
        [new() { Key = "key2", Value = "value2"}]
    ]
    });

    context.SaveChanges();

    return context.MyEntity.ToList();
}).WithName("ErroJsonb");

Sorry, in DB it looks like in the photo, but you're right, the EF mapping comes back to me correctly: [{"id":3,"jsonbFields":[[{"key":"key1","value":"value1"}],[{"key":"key2","value":"value2"}]]}]

Why isn't it written in plain text in DB?

from efcore.pg.

zN3utr4l avatar zN3utr4l commented on June 15, 2024

I changed the endpoint like this, to make the list of lists look like the json I sent initially, but now the entity I inserted before seems to no longer be serialized.

app.MapGet("/error-jsonb", ([FromServices] CustomDbContext context) =>
{
    MyEntity a = new()
    {
        JsonbFields = [
            [new() { Key = "key1", Value = "value1"}, new() { Key = "key2", Value = "value2"}],
            [new() { Key = "key1", Value = "value1"}, new() { Key = "key2", Value = "value2" }]
        ]
    };

    context.Add(a);

    context.SaveChanges();

    return context.MyEntity.ToList();
}).WithName("ErroJsonb");

image

[
   {
      "id":3,
      "jsonbFields":[
         [
            
         ],
         [
            
         ]
      ]
   },
   {
      "id":4,
      "jsonbFields":[
         [
            {
               "key":"key1",
               "value":"value1"
            },
            {
               "key":"key2",
               "value":"value2"
            }
         ],
         [
            {
               "key":"key1",
               "value":"value1"
            },
            {
               "key":"key2",
               "value":"value2"
            }
         ]
      ]
   }
]

Every time I rerun the program, the entity inserted in the last execution is no longer mapped and is empty as in the json sent above

from efcore.pg.

roji avatar roji commented on June 15, 2024

@zN3utr4l it really would be easiest if you could submit a simple console program - just a single page of code - which shows the exception happening. I'm spending a lot of time trying to understand all the snippets and screenshots above.

from efcore.pg.

zN3utr4l avatar zN3utr4l commented on June 15, 2024

I put the ErrorNpgsqlJsonb project (https://github.com/zN3utr4l/ErrorNpgsql-ListOfLists-Jsonb), which is a console app, all in one file, hope it's fine now.

run the app console a first time and it should print the entities it created, but if you relaunch the app console a second time, you will see how the old created entities are not printed, they appear to be of type: Castle.Proxies.List1Proxy instead of System.Collections.Generic.List1[ErrorNpgsqlJsonb.JsonbField]

from efcore.pg.

roji avatar roji commented on June 15, 2024

I've taken another look, and I can't see the original error you reported above (Invalid token type: 'StartArray'.), are you now reporting a new problem? Is the original error gone? If so, it's better to not mix two problems in the same issue, but to open a new issue instead.

In any case, regarding the ToString() printing Castle.Proxies... - that's very likely by design; when you use LazyLoadingProxies, you're opting in to receiving proxies instead of your original entity types, and that's what the ToString() is showing. This happens only in the 2nd run since in the 1st run, the original entity type is still tracked by the context (from when you added it), and so that's returned. The 2nd time, a proxy is returned instead (see below for a simplified one-run repro where everything is in the same program).

/cc @ajcvickers for this possibly interesting "inconsistent" behavior; but to me everything seems like it's working as expected.

Simplified code sample, with a single run

from efcore.pg.

zN3utr4l avatar zN3utr4l commented on June 15, 2024

image

Above I inserted the screen of PGAdmin with what is inserted in the JsonbFields field, I don't think it's correct, it is inserting the information of the first nested list i think, and not the content of the json.

[
  {
    "Capacity": 4
  },
  {
    "Capacity": 4
  }
]

This is the plain text that is in db, it's not an object, it's exactly how you read it.

From this it seems clear to me that something is wrong.
As you can see, however, in the object above (which I manually inserted directly with PgAdmin) the plain text is correct.

This means that EF is writing to db wrong.

image

In fact, when I go to get the entities I get an empty object back, even though I had inserted the JsonbFields correctly

from efcore.pg.

ajcvickers avatar ajcvickers commented on June 15, 2024

@roji What you describe is by-design.

from efcore.pg.

zN3utr4l avatar zN3utr4l commented on June 15, 2024

Sorry for insisting but I don't understand if you don't consider this error a bug.

As I understand it, @roji doesn't consider it a bug, but in my opinion it's because, as I have repeated many times, you have to look at the db with PgAdmin, if you look at what it saves in the JsonBFields field you would immediately notice the problem.

from efcore.pg.

roji avatar roji commented on June 15, 2024

@zN3utr4l you originally reported an error with Invalid token type: 'StartArray'.; I asked you to provide a repro for that, but I haven't seen one yet.

In this comment of yours you asked a completely unrelated question regarding the ToString() behavior when using Castles.Proxies - both @ajcvickers and I consider this to be by design (no bug).

Now, if you want us to look into the original bug (Invalid token type: 'StartArray'.), you're going to have to provide an actual repro - I need to be able to see the bug happening here. Otherwise I have to assume that you maybe have bad/malformed JSON data in your actual database, and EF is erroring on that.

from efcore.pg.

zN3utr4l avatar zN3utr4l commented on June 15, 2024

ToString() when using Castles.Proxies was a question, not a bug report.

you have to look at the db with PgAdmin, if you look at what it saves in the JsonBFields field you would immediately notice the problem.

But did you check this after running my repro?

The error Invalid token type: 'StartArray'.; it is generated by the fact that the Lists of List in the jsonb field are not saved correctly and some middleware that I had in the app (not in the repro) was unable to serialize.

look, let's do something, I'll open another issue where I don't refer to Invalid token type: 'StartArray'. But only to the fact that it is not saved correctly.

from efcore.pg.

roji avatar roji commented on June 15, 2024

it is generated by the fact that the Lists of List in the jsonb field are not saved correctly and some middleware that I had in the app (not in the repro) was unable to serialize.
[...]
I'll open another issue where I don't refer to Invalid token type: 'StartArray'. But only to the fact that it is not saved correctly.

From the above it sounds like you have some invalid JSON in your database, which wasn't generated by EF; if that's the case, then EF is behaving correctly.

If you believe EF itself is the one generating invalid JSON in SaveChanges, please submit a repro to show that.

from efcore.pg.

zN3utr4l avatar zN3utr4l commented on June 15, 2024

Look, I don't know if I don't know how to explain myself or there is some other communication problem, the repro I made already shows this error.

Follow these simple steps.

  1. Launch the app console.
  2. Look at the output and keep the last id in mind, see if it reads well.
    image
  3. Relaunch the app console.
  4. Note that the previous id which was read correctly is now completely empty.
    image
  5. Open PgAdmin.
  6. Note that, as in the images I sent you, the json does not actually contain the data I wrote in the app console, but contains, I'm not sure, information regarding the first list.
    image

Please do exactly as I wrote, because I've been repeating it for 10 comments and I don't think you've done it, otherwise you would have already noticed that something is wrong.

from efcore.pg.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.