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

Storing Auto-generated TS Vector from Unmapped Fields #3352

Open
Foorcee opened this issue Nov 6, 2024 · 1 comment
Open

Storing Auto-generated TS Vector from Unmapped Fields #3352

Foorcee opened this issue Nov 6, 2024 · 1 comment

Comments

@Foorcee
Copy link

Foorcee commented Nov 6, 2024

I would like to store only a tsvector column in my PostgreSQL table without saving the original text itself. To achieve this, I have created a text variable in my model class and marked it with [NotMapped].

The model is configured so that the tsvector column is automatically generated based on the content of this unmapped text property. It would be very helpful if EF Core could support storing auto-generated tsvector columns derived from unmapped fields, allowing us to keep the tsvector for full-text search while avoiding storage of the raw text.

Model:

    [NotMapped]
    public required string FullTextSearch { get; set; }
    public NpgsqlTsVector FullSearchVector { get; set; } 

Model Configuration:

builder.HasGeneratedTsVectorColumn(record => record.FullSearchVector, 
       "english",
        record => record.FullTextSearch);

Exception:

 System.NullReferenceException: Object reference not set to an instance of an object.
         at Microsoft.EntityFrameworkCore.Metadata.Internal.RelationalPropertyOverrides.Find(IReadOnlyProperty property, StoreObjectIdentifier& storeObject)
         at Microsoft.EntityFrameworkCore.RelationalPropertyExtensions.FindOverrides(IReadOnlyProperty property, StoreObjectIdentifier& storeObject)
         at Microsoft.EntityFrameworkCore.RelationalPropertyExtensions.GetColumnName(IReadOnlyProperty property, StoreObjectIdentifier& storeObject)
         at Npgsql.EntityFrameworkCore.PostgreSQL.Metadata.Internal.NpgsqlAnnotationProvider.<>c__DisplayClass2_1.<For>b__10(String p2)
         at System.Linq.Enumerable.SelectArrayIterator`2.Fill(ReadOnlySpan`1 source, Span`1 destination, Func`2 func)
         at System.Linq.Enumerable.SelectArrayIterator`2.ToArray()
         at Npgsql.EntityFrameworkCore.PostgreSQL.Metadata.Internal.NpgsqlAnnotationProvider.For(IColumn column, Boolean designTime)+MoveNext()
         at Microsoft.EntityFrameworkCore.Infrastructure.AnnotatableBase.AddAnnotations(AnnotatableBase annotatable, IEnumerable`1 annotations)
         at Microsoft.EntityFrameworkCore.Infrastructure.AnnotatableBase.AddAnnotations(IEnumerable`1 annotations)
         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_DesignTimeModel()
         at Microsoft.EntityFrameworkCore.Metadata.Internal.DesignTimeModel.get_Model()
         at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.NpgsqlDatabaseCreator.CreateTablesAsync(CancellationToken cancellationToken)
         at Microsoft.EntityFrameworkCore.Storage.RelationalDatabaseCreator.EnsureCreatedAsync(CancellationToken cancellationToken)
         at Microsoft.EntityFrameworkCore.Storage.RelationalDatabaseCreator.EnsureCreatedAsync(CancellationToken cancellationToken)
@roji
Copy link
Member

roji commented Nov 6, 2024

I'm not sure I understand; if the property (FullTextSearch) is unmapped, that means that there's no column in the database that corresponds to it; and if that's the case, where do you want your tsvector column to be generated from exactly? Do you want the column to be in the database, but simply unmapped via EF? If that's the case, then you can simply use EF's HasComputedSql() instead of HasGeneratedTsVectorColumn() and directly provide the SQL referencing the text column (HasGeneratedTsVectorColumn is nothing more than some thin sugar over HasComputedSql).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants