Search code examples
.net-coreentity-framework-corexaf

How to set the table name for TPH class?


I know it is possible to set the table name in the DbContext's OnModelCreating override. However I run into problems trying to do this when the business object inherits from a base class.

My business object ( from xaf) is

[DefaultProperty(nameof(UserName))]
public class ApplicationUser : PermissionPolicyUser, 
IObjectSpaceLink, ISecurityUserWithLoginInfo {
public ApplicationUser() : base() {
   UserLogins = new List<ApplicationUserLoginInfo>();
}

[Browsable(false)]
[DevExpress.ExpressApp.DC.Aggregated]
public virtual IList<ApplicationUserLoginInfo> UserLogins { get; set; }
IEnumerable<ISecurityUserLoginInfo> IOAuthSecurityUser.UserLogins => UserLogins.OfType<ISecurityUserLoginInfo>();

ISecurityUserLoginInfo ISecurityUserWithLoginInfo.CreateUserLoginInfo(string loginProviderName, string providerUserKey) {
    ApplicationUserLoginInfo result = ((IObjectSpaceLink)this).ObjectSpace.CreateObject<ApplicationUserLoginInfo>();
    result.LoginProviderName = loginProviderName;
    result.ProviderUserKey = providerUserKey;
    result.User = this;
    return result;
}

}

My DbContext is like this

public class JTEFCoreDbContext : DbContext {
 public JTEFCoreDbContext(DbContextOptions<JTEFCoreDbContext> options) : base(options) 
 {
    
 }
 public DbSet<ApplicationUser> Users { get; set; }
 // etc

 protected override void OnModelCreating(ModelBuilder modelBuilder) {
 modelBuilder.Entity<ApplicationUserLoginInfo>(b =>
 {
   modelBuilder.Entity<ApplicationUser>().ToTable("PermissionPolicyUsers");  
  // etc

My unit test is like this

using System.Configuration;
using System.Diagnostics;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using Microsoft.VisualStudio.TestTools.UnitTesting;
namespace TestProject1
{
    [TestClass]
    public class UnitTest1
    {
        [TestMethod]
        public void TestMethod1()
        {
            var connectionString =
                "Server=myserver;Database=mydb;Integrated Security=false;MultipleActiveResultSets=True;user=sa;pwd=mypassword";
            var optionsBuilder = new DbContextOptionsBuilder<JTEFCoreDbContext>().UseSqlServer(connectionString);
            var options = optionsBuilder.Options;
            var db = new JTEFCoreDbContext(options);
            var user =db.Users.FirstOrDefault();   // fails with error 
        }
    }
}

The error is

Microsoft.Data.SqlClient.SqlException: Invalid object name 'PermissionPolicyUser'

The test project is

 <Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net5.0</TargetFramework>

    <IsPackable>false</IsPackable>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.4" />
    <PackageReference Include="MSTest.TestAdapter" Version="2.2.3" />
    <PackageReference Include="MSTest.TestFramework" Version="2.2.3" />
    <PackageReference Include="coverlet.collector" Version="3.0.2" />
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="..\JT2Core.Module\JT2Core.Module.csproj" />
  </ItemGroup>

  <ItemGroup>
    <Compile Update="Properties\Resources.Designer.cs">
      <DesignTime>True</DesignTime>
      <AutoGen>True</AutoGen>
      <DependentUpon>Resources.resx</DependentUpon>
    </Compile>
  </ItemGroup>

  <ItemGroup>
    <EmbeddedResource Update="Properties\Resources.resx">
      <Generator>ResXFileCodeGenerator</Generator>
      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
    </EmbeddedResource>
  </ItemGroup>

</Project>

The module project is

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net5.0</TargetFramework>
    <Deterministic>false</Deterministic>
    <AssemblyVersion>1.0.*</AssemblyVersion>
    <FileVersion>1.0.0.0</FileVersion>
    <Configurations>Debug;Release;EasyTest</Configurations>
  </PropertyGroup>
  <ItemGroup>
    <None Remove="Model.DesignedDiffs.xafml" />
  </ItemGroup>
  <ItemGroup>
    <EmbeddedResource Include="Model.DesignedDiffs.xafml" />
  </ItemGroup>
  <ItemGroup>
    <PackageReference Include="DevExpress.ExpressApp" Version="21.2.5" />
    <PackageReference Include="DevExpress.ExpressApp.CodeAnalysis" Version="21.2.5" />
    <PackageReference Include="DevExpress.ExpressApp.ConditionalAppearance" Version="21.2.5" />
    <PackageReference Include="DevExpress.ExpressApp.EFCore" Version="21.2.5" />
    <PackageReference Include="DevExpress.ExpressApp.Validation" Version="21.2.5" />
    <PackageReference Include="DevExpress.Persistent.Base" Version="21.2.5" />
    <PackageReference Include="DevExpress.Persistent.BaseImpl.EFCore" Version="21.2.5" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="5.0.0" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="5.0.0" />
  </ItemGroup>
</Project>

Solution

  • I managed to get a unit test working by setting both classes to use the table name

    In OnModelCreating

    modelBuilder.Entity<ApplicationUser>().ToTable("PermissionPolicyUsers");
    modelBuilder.Entity<PermissionPolicyUser>().ToTable("PermissionPolicyUsers");
    

    Cross linking to the Dev Express Ticket