When this code runs (FYI, the generic <TDbEntity>
is a VgnItmDbEntity
):
var entity = await context.Set<TDbEntity>().Include(e => e.VgnItmImages)
.ThenInclude(vi => vi.Image)
.FirstOrDefaultAsync(v => v.Id == id);
I get the error:
Exception has occurred: CLR/Npgsql.PostgresException Exception thrown:
‘Npgsql.PostgresException’ in System.Private.CoreLib.dll: ‘42703:
column v0.VgnItmDbEntityId does not existPOSITION: 1163′ at
Npgsql.Internal.NpgsqlConnector.d__233.MoveNext()
at
System.Runtime.CompilerServices.PoolingAsyncValueTaskMethodBuilder1.StateMachineBox
1.System.Threading.Tasks.Sources.IValueTaskSource.GetResult(Int16
token) at Npgsql.NpgsqlDataReader.d__52.MoveNext()
at Npgsql.NpgsqlDataReader.d__52.MoveNext() at
Npgsql.NpgsqlCommand.d__119.MoveNext() at
Npgsql.NpgsqlCommand.d__119.MoveNext() at
Npgsql.NpgsqlCommand.d__112.MoveNext() at
Microsoft.EntityFrameworkCore.Storage.RelationalCommand.d__18.MoveNext()
at
Microsoft.EntityFrameworkCore.Storage.RelationalCommand.d__18.MoveNext()
at
Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable1.AsyncEnumerator.<InitializeReaderAsync>d__21.MoveNext() at Npgsql.EntityFrameworkCore.PostgreSQL.Storage.Internal.NpgsqlExecutionStrategy.<ExecuteAsync>d__7
2.MoveNext()
at
Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable1.AsyncEnumerator.<MoveNextAsync>d__20.MoveNext() at System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable
1.ConfiguredValueTaskAwaiter.GetResult()
at
Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.d__151.MoveNext() at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.<SingleOrDefaultAsync>d__15
1.MoveNext()
at Vepo.Data.VgnItmsRepository`5.d__9.MoveNext() in
/Users/benjaminfarquhar/dev/vepo_back_end/Vepo.Data/Repositories/VgnItms/VgnItmsRepository.cs:line
144
These are my entities and their configuration in OnModelCreating
:
public class VgnItmDbEntity : CreatedBySomeoneDbEntity
{
[Required]
public string Name { get; set; }
[Required]
public string CompanyName { get; set; }
[MaxLength(3000)]
public string Description { get; set; }
[MaxLength(900)]
public string WebPage { get; set; }
public string Instagram { get; set; }
public string Facebook { get; set; }
[Required]
public int IsNotVeganCount { get; set; } = 0;
[Required]
public int IsVeganCount { get; set; } = 0;
[Required]
public int RatingsCount { get; set; } = 0;
public double? Rating { get; set; }
[Required]
public List<int> Tags { get; set; }
public List<int> SecondaryTags { get; set; }
public int? PricePoint { get; set; }
public ICollection<VgnItmImageDbEntity> VgnItmImages { get; set; }
public string Discriminator { get; set; }
}
public class VgnItmImageDbEntity : CreatedBySomeoneDbEntity
{
[ForeignKey(nameof(VgnItm))]
public int VgnItmId { get; set; }
public VgnItmDbEntity VgnItm { get; set; }
[ForeignKey(nameof(Image))]
public int ImageId { get; set; }
public ImageDbEntity Image { get; set; }
}
public class ImageDbEntity : CreatedBySomeoneDbEntity
{
[Required]
public Uri Url { get; set; }
public List<int> Tags { get; set; }
public ICollection<VgnItmImageDbEntity> VgnItmImages { get; set; } = new List<VgnItmImageDbEntity>();
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
var uriConverter = new ValueConverter<Uri, string>(
v => v == null ? null : v.ToString(),
v => v == null ? null : new Uri(v)
);
modelBuilder.Entity<ImageDbEntity>(image =>
{
image.Property(u => u.CreatedDate)
.HasDefaultValueSql("CURRENT_TIMESTAMP");
image.Property(u => u.UpdatedDate)
.HasDefaultValueSql("CURRENT_TIMESTAMP");
image.Property(i => i.Url)
.HasConversion(uriConverter);
});
// Vegan Item Images
modelBuilder.Entity<VgnItmImageDbEntity>(viImage =>
{
viImage.HasKey(e => new { e.VgnItmId, e.ImageId });
viImage.HasOne(e => e.VgnItm)
.WithMany(v => v.VgnItmImages)
.HasForeignKey(e => e.VgnItmId);
viImage.HasOne(e => e.Image)
.WithMany(i => i.VgnItmImages)
.HasForeignKey(e => e.ImageId);
viImage.HasIndex(g => new { g.VgnItmId, g.ImageId }).IsUnique();
viImage.Property(e => e.Id).IsRequired().ValueGeneratedOnAdd();
viImage.Property(u => u.CreatedDate)
.HasDefaultValueSql("CURRENT_TIMESTAMP");
viImage.Property(u => u.UpdatedDate)
.HasDefaultValueSql("CURRENT_TIMESTAMP");
viImage.HasOne(q => q.UpdatedBy)
.WithMany()
.HasForeignKey(k => k.UpdatedById);
viImage.HasOne(q => q.CreatedBy)
.WithMany()
.HasForeignKey(k => k.CreatedById);
});
modelBuilder.Entity<VgnItmDbEntity>(vgnItm =>
{
vgnItm.HasIndex("CompanyName", "Name", "Discriminator").IsUnique();
vgnItm.Property(e => e.Id).IsRequired().ValueGeneratedOnAdd();
vgnItm.HasDiscriminator<string>("Discriminator")
.HasValue<RecipeItmDbEntity>("RecipeItm")
.HasValue<EventItmDbEntity>("EventItm")
.HasValue<GroceryItmDbEntity>("GroceryItm")
.HasValue<MenuItmDbEntity>("MenuItm")
.HasValue<RestaurantItmDbEntity>("RestaurantItm")
.HasValue<GroceryStoreItmDbEntity>("GroceryStoreItm")
.HasValue<FashionItmDbEntity>("FashionItm");
vgnItm.Property(u => u.CreatedDate)
.HasDefaultValueSql("CURRENT_TIMESTAMP");
vgnItm.Property(u => u.UpdatedDate)
.HasDefaultValueSql("CURRENT_TIMESTAMP");
vgnItm.HasKey(e => e.Id);
vgnItm.HasOne(q => q.UpdatedBy)
.WithMany()
.HasForeignKey(k => k.UpdatedById);
vgnItm.HasOne(q => q.CreatedBy)
.WithMany()
.HasForeignKey(k => k.CreatedById);
vgnItm.HasMany(e => e.VgnItmImages)
.WithOne()
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity<RecipeItmDbEntity>(recipeItm =>
{
recipeItm.Property(e => e.Ingredients).HasColumnType("jsonb");
recipeItm.Property(e => e.Method).HasMaxLength(100);
recipeItm.Property(e => e.Tips).HasMaxLength(20);
recipeItm.Property(e => e.Ingredients).HasMaxLength(100);
});
modelBuilder.Entity<SingleLocationVgnItmDbEntity>(singleLocationVgnItm =>
{
singleLocationVgnItm.HasIndex("CompanyName", "Name", "Discriminator", "LocationId").IsUnique();
singleLocationVgnItm
.HasOne(s => s.Location) // Each SingleLocationVgnItm has one Location.
.WithMany() // A Location can be associated with many SingleLocationVgnItm.
.HasForeignKey(s => s.LocationId); // Foreign key in SingleLocationVgnItm pointing to Location.
});
The field name is actaully VgnItmId
, not VgnItmDbEntityId
. I do not want any of my automatically generated EF core fields to have DbEntity
in the name. I had to do a manual migration to remove the VgnItmDbEntityId
column, but EF Core still thinks it exists when doing runtime queries in the code. How do I let EF Core know that the name of the field is not VgnItmDbEntityId
, but rather VgnItmId
?