-
Notifications
You must be signed in to change notification settings - Fork 3.3k
Description
Do we have a way to use InMemoryDatabase with HierarchyId?
I'm testing the new HierarchyId support of EF Core.
To enable that for SqlServerDatabase, we have to call UseHierarchyId when we setup the DbContext:
services.AddDbContext<MyDbContext>(options =>
{
options.UseSqlServer(connectionString, x => x.UseHierarchyId());
});I have a Unit test projet that is using a InMemoryDatabase, but I don't find a way to add an equivalency of that UseHierarchyId that would allow me to unit test code that rely on HierarchyId. Do I miss something?
I think efcore/EFCore.SqlServer.HierarchyId#33 was including that kind of capabilities in the kmataru/EFCore.SqlServer.HierarchyId project, but I don't find that code in https://github.com/dotnet/efcore/tree/main/src/EFCore.InMemory?
Without that support, I'm getting exceptions in my Unit tests:
using Microsoft.EntityFrameworkCore;
namespace HierarchyId.Tests;
public sealed class TestHierarchyIdTests
{
public class Contact
{
public int Id { get; set; }
public HierarchyId HierarchyId { get; set; }
}
public class MyDbContext : DbContext
{
public MyDbContext(DbContextOptions<MyDbContext> options) : base(options)
{
}
public DbSet<Contact> Contacts { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Contact>()
.HasKey(c => c.Id);
modelBuilder.Entity<Contact>()
.HasIndex(x => x.HierarchyId)
.IsUnique();
}
}
[Fact]
public async Task Test_HierarchyId()
{
var inMemoryDbOptions = new DbContextOptionsBuilder<MyDbContext>()
.UseInMemoryDatabase("Test_HierarchyId")
.Options;
var context = new MyDbContext(inMemoryDbOptions);
var contact = new Contact
{
HierarchyId = HierarchyId.Parse("/"),
};
await context.Set<Contact>().AddAsync(contact);
}
} Message:
System.InvalidOperationException : The entity type 'HierarchyId' requires a primary key to be defined. If you intended to use a keyless entity type, call 'HasNoKey' in 'OnModelCreating'. For more information on keyless entity types, see https://go.microsoft.com/fwlink/?linkid=2141943.
Stack Trace:
Message:
System.InvalidOperationException : The 'HierarchyId' property 'Contact.HierarchyId' could not be mapped because the database provider does not support this type. Consider converting the property value to a type supported by the database using a value converter. See https://aka.ms/efcore-docs-value-converters for more information. Alternately, exclude the property from the model using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.
Stack Trace:
ModelValidator.ThrowPropertyNotMappedException(String propertyType, IConventionTypeBase typeBase, IConventionProperty unmappedProperty)
ModelValidator.<ValidatePropertyMapping>g__Validate|7_0(IConventionTypeBase typeBase, <>c__DisplayClass7_0&)
ModelValidator.ValidatePropertyMapping(IModel model, IDiagnosticsLogger`1 logger)
ModelValidator.Validate(IModel model, IDiagnosticsLogger`1 logger)
InMemoryModelValidator.Validate(IModel model, IDiagnosticsLogger`1 logger)
ModelRuntimeInitializer.Initialize(IModel model, Boolean designTime, IDiagnosticsLogger`1 validationLogger)
ModelSource.GetModel(DbContext context, ModelCreationDependencies modelCreationDependencies, Boolean designTime)
DbContextServices.CreateModel(Boolean designTime)
DbContextServices.get_Model()
<>c.<TryAddCoreServices>b__8_4(IServiceProvider p)
<32 more frames...>
ServiceProviderEngineScope.GetService(Type serviceType)
ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
DbContext.get_DbContextDependencies()
DbContext.get_ContextServices()
DbContext.get_InternalServiceProvider()
DbContext.get_DbContextDependencies()
DbContext.Set[TEntity]()
TestHierarchyIdTests.Test_HierarchyId() line 43
--- End of stack trace from previous location ---
Provider and version information
EF Core version: 8.0.0-rc.2.23480.1
Database provider: Microsoft.EntityFrameworkCore.InMemory
Target framework: .NET 8.0
Operating system: Microsoft Windows 11 Pro
IDE: Microsoft Visual Studio Professional 2022 (64-bit) - Preview