Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SqlLite does not support ToJson()? #31094

Closed
MacMcDell opened this issue Jun 16, 2023 · 4 comments
Closed

SqlLite does not support ToJson()? #31094

MacMcDell opened this issue Jun 16, 2023 · 4 comments

Comments

@MacMcDell
Copy link

using <PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.7" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.5">

usage - Class Library Unit Testing

This issue tracker is for -
I am attempting to run SQLLite In Memory db for my unit testing and following the following supported documentation here: https://github.com/dotnet/EntityFramework.Docs/blob/main/samples/core/Testing/TestingWithoutTheDatabase/SqliteInMemoryBloggingControllerTest.cs

Unfortunately every time it attempts to add objects of any complexity, I am getting a crash at this point with the following message:
In RelationalModel.cs (line 469) I am getting a NRE on the following column within one of my DBSets.

I can only assume this has something to do with my OnModelCreating setup code:

 modelBuilder.Entity<MyDbMap>(entity =>
        {
            entity.ToTable("MyDbMaps");
            entity.Property(e => e.Id).ValueGeneratedOnAdd();
            entity.HasKey(e => new { e.CustomerId, e.MyDbPartnerId });
            entity.HasOne(d => d.MyDbPartner).WithMany(p => p.MyDbMaps)
                .HasForeignKey(d => d.MyDbPartnerId)
                .OnDelete(DeleteBehavior.ClientSetNull)
                .HasConstraintName("FK_MyDbMaps_MyDbPartner");
                // THIS SECTION I ASSUME IS BAD? 
            entity.OwnsOne(x => x.Mappings, b =>
            {
                b.ToJson();
                b.OwnsMany<MatchSuccess>(x => x.MatchSuccess,
                    successbuilder =>
                    {
                        successbuilder.Property(x => x.Meta)
                            .HasConversion(
                                v => JsonSerializer.Serialize(v, new JsonSerializerOptions()),
                                v => JsonSerializer.Deserialize<Dictionary<string, string>>(v,
                                    new JsonSerializerOptions() { }));
                        successbuilder.ToJson();
                    });
                b.OwnsMany<MatchFailure>(x => x.MatchFailures,
                    failureBuilder => failureBuilder.ToJson<MappingResponse, MatchFailure>());
            });
        });
System.NullReferenceException: Object reference not set to an instance of an object.
   at Microsoft.EntityFrameworkCore.Metadata.Internal.RelationalModel.CreateTableMapping(IRelationalTypeMappingSource relationalTypeMappingSource, IEntityType entityType, IEntityType mappedType, StoreObjectIdentifier mappedTable, RelationalModel databaseModel, List`1 tableMappings, Boolean includesDerivedTypes, Nullable`1 isSplitEntityTypePrincipal)
   at Microsoft.EntityFrameworkCore.Metadata.Internal.RelationalModel.AddTables(RelationalModel databaseModel, IEntityType entityType, IRelationalTypeMappingSource relationalTypeMappingSource)
   at Microsoft.EntityFrameworkCore.Metadata.Internal.RelationalModel.Create(IModel model, IRelationalAnnotationProvider relationalAnnotationProvider, IRelationalTypeMappingSource relationalTypeMappingSource, Boolean designTime)
   at Microsoft.EntityFrameworkCore.Metadata.Internal.RelationalModel.Add(IModel model, IRelationalAnnotationProvider relationalAnnotationProvider, IRelationalTypeMappingSource relationalTypeMappingSource, Boolean designTime)
   at Microsoft.EntityFrameworkCore.Infrastructure.RelationalModelRuntimeInitializer.InitializeModel(IModel model, Boolean designTime, Boolean prevalidation)
   at Microsoft.EntityFrameworkCore.Infrastructure.ModelRuntimeInitializer.Initialize(IModel model, Boolean designTime, IDiagnosticsLogger`1 validationLogger)
   at Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.GetModel(DbContext context, ModelCreationDependencies modelCreationDependencies, Boolean designTime)
   at Microsoft.EntityFrameworkCore.Internal.DbContextServices.CreateModel(Boolean designTime)
   at Microsoft.EntityFrameworkCore.Internal.DbContextServices.get_Model()

Implementation ## - following almost verbatim of the provided sqlLite example

public class SqliteInMemoryBloggingControllerTest : IDisposable
{
    private readonly DbConnection _connection;
    private readonly DbContextOptions<MyDbDbContext> _contextOptions;

    #region ConstructorAndDispose

    public SqliteInMemoryBloggingControllerTest()
    {
        // Create and open a connection. This creates the SQLite in-memory database, which will persist until the connection is closed
        // at the end of the test (see Dispose below).
        _connection = new SqliteConnection("Filename=:memory:");
        _connection.Open();

        // These options will be used by the context instances in this test suite, including the connection opened above.
        _contextOptions = new DbContextOptionsBuilder<MyDbDbContext>()
            .UseSqlite(_connection)
            .Options;

        // Create the schema and seed some data
        using var context = new MyDbDbContext(_contextOptions);

        
        context.MyDbPartners.AddRange(FakeRepository.MyDbPartners());
        context.MyDbMaps.AddRange(FakeRepository.MyDbMaps());
        context.MyDbPolicies.AddRange(FakeRepository.MyDbPolicies());
        context.MyDbPolicySpaces.Add(new MyDbPolicySpaces()
        {
            MyDbPartnerId = (int)Partner.Foo,
            MyDbPolicyId = 1,
            Spaces = new Dictionary<string, string>()
            {
                { "236129", "12341" },
                { "50159", "12340" },
                { "269506", "1234" }

            },

        });
        
        
        context.SaveChanges();
    }

    MyDbDbContext CreateContext() => new MyDbDbContext(_contextOptions);

    public void Dispose() => _connection.Dispose();


    [TestMethod]
    public void GetBlog()
    {
        using MyDbDbContext context = CreateContext();

        var result = context.MyDbMaps.ToList(); 
        Assert.IsTrue(result.Count > 0);

    }

image

@MacMcDell
Copy link
Author

This problem seems to erupt from the jsonColumnTypeMapping.
image

it goes into this FindMappingWithConversion.. of clrType = System.Text.Json.. but the principals is null.. so it hits a lower down overload where it FindMappingWithConversion(mappingInfo, null, null)
image

finally resolvedMapping is null.. ..so everything donwnstream is null.

@roji
Copy link
Member

roji commented Jun 16, 2023

JSON columns support isn't available for SQLite in EF Core 7 - this has been implemented for the upcoming 8.0 (docs). You can try the latest 8.0 preview to see the feature at work.

@maumar
Copy link
Contributor

maumar commented Jun 17, 2023

dupe of #28816

@MacMcDell
Copy link
Author

Thanks for this update. I will check it out.

@maumar maumar closed this as completed Jun 18, 2023
@roji roji closed this as not planned Won't fix, can't repro, duplicate, stale Jun 18, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants