0

Source code for this problem is on GitHub

I have the following dbContext for a legacy data structure.

[TypesInfoInitializer(typeof(OrgsContextInitializer))]
public class OrgsEFCoreDbContext : DbContext
{
    public OrgsEFCoreDbContext(DbContextOptions<OrgsEFCoreDbContext> options) : base(options)
    {
    }
    public DbSet<ModuleInfo> ModulesInfo { get; set; }
    public DbSet<ModelDifference> ModelDifferences { get; set; }
    public DbSet<ModelDifferenceAspect> ModelDifferenceAspects { get; set; }
    public DbSet<PermissionPolicyRole> Roles { get; set; }
    public DbSet<ApplicationUser> Users { get; set; }
    public DbSet<ApplicationUserLoginInfo> UserLoginInfos { get; set; }

    public DbSet<Customer> Customers { get; set; }
    public DbSet<Supplier> Suppliers { get; set; }

    public DbSet<CustomerContact> CustomerContacts { get; set; }
    public DbSet<SupplierContact> SupplierContacts { get; set; }


    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<ApplicationUserLoginInfo>(b =>
        {
            b.HasIndex(nameof(DevExpress.ExpressApp.Security.ISecurityUserLoginInfo.LoginProviderName), nameof(DevExpress.ExpressApp.Security.ISecurityUserLoginInfo.ProviderUserKey)).IsUnique();
        });

        modelBuilder.Entity<Organization>().ToTable("Organizations");
        modelBuilder.Entity<Organization>().HasDiscriminator(x => x.OrganizationType)
            .HasValue<Customer>(1)
            .HasValue<Supplier>(2)
            ;

        modelBuilder.Entity<Contact>().ToTable("Contacts");
        modelBuilder.Entity<Contact>().HasDiscriminator(x => x.ContactType)
            .HasValue<CustomerContact>(1)
            .HasValue<SupplierContact>(2)
            ;
    }
}

When I add a CustomerContact to a Customer I get an error

Unable to cast object of type 'Orgs.Module.BusinessObjects.CustomerContact' to type 'Orgs.Module.BusinessObjects.SupplierContact'.

   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.get_Item(IPropertyBase propertyBase)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.GetCurrentValue(IPropertyBase propertyBase)
   at DevExpress.EntityFrameworkCore.Security.NetStandard.ChangeTracking.SecurityStateManager.TryAddPropertyNameToCollection(InternalEntityEntry entity, ICollection`1 propertiesToCheck, IPropertyBase property)
   at DevExpress.EntityFrameworkCore.Security.NetStandard.ChangeTracking.SecurityStateManager.TryAddPropertyNameToCollection(InternalEntityEntry entity, IProperty property, ICollection`1 propertiesToCheck)
   at DevExpress.EntityFrameworkCore.Security.NetStandard.ChangeTracking.SecurityStateManager.GetPropertiesToCheck(InternalEntityEntry entity)
   at DevExpress.EntityFrameworkCore.Security.NetStandard.ChangeTracking.SecurityStateManager.CheckReadWritePermissionsForNonIntermediateObject(InternalEntityEntry entity)
   at DevExpress.EntityFrameworkCore.Security.NetStandard.ChangeTracking.SecurityStateManager.CheckReadWritePermissions(InternalEntityEntry entity)
   at DevExpress.EntityFrameworkCore.Security.NetStandard.ChangeTracking.SecurityStateManager.CheckIsGrantedToSave(InternalEntityEntry entity)
   at DevExpress.EntityFrameworkCore.Security.NetStandard.ChangeTracking.SecurityStateManager.GetEntriesToSave(Boolean cascadeChanges)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(DbContext _, Boolean acceptAllChangesOnSuccess)
   at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.Execute[TState,TResult](TState state, Func`3 operation, Func`3 verifySucceeded)
   at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChanges(Boolean acceptAllChangesOnSuccess)
   at Microsoft.EntityFrameworkCore.DbContext.SaveChanges(Boolean acceptAllChangesOnSuccess)
   at Microsoft.EntityFrameworkCore.DbContext.SaveChanges()
   at DevExpress.ExpressApp.EFCore.EFCoreObjectSpace.DoCommit()
   at DevExpress.EntityFrameworkCore.Security.SecuredEFCoreObjectSpace.DoCommit()
   at DevExpress.ExpressApp.BaseObjectSpace.CommitChanges()
   at DevExpress.ExpressApp.Win.SystemModule.WinModificationsController.Save(SimpleActionExecuteEventArgs args)
   at DevExpress.ExpressApp.SystemModule.ModificationsController.saveAction_OnExecute(Object sender, SimpleActionExecuteEventArgs e)
   at DevExpress.ExpressApp.Actions.SimpleAction.RaiseExecute(ActionBaseEventArgs eventArgs)
   at DevExpress.ExpressApp.Actions.ActionBase.ExecuteCore(Delegate handler, ActionBaseEventArgs eventArgs)

The error is the other way around if I try to add a supplier contact to a supplier.

The business classes are as follows;

[NavigationItem("Data")]
public class Customer : Organization
{
    public Customer()
    {
        Contacts = new List<CustomerContact>();
    }
    public virtual List<CustomerContact> Contacts { get; set; }
}

public class CustomerContact : Contact
{
    public CustomerContact() {}

    [ForeignKey("OrganizationId")]
    public virtual Customer Customer { get; set; }
}

public abstract class Organization
{
    [Key]
    public int Id { get; set; }
    public string Name { get; set; }
    public string Phone { get; set; }
    public string Comments { get; set; }
    public int OrganizationType { get; set; }
}

public abstract class Contact
{
    [Key]
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int ContactType { get; set; }
    public int OrganizationId { get; set; }
}

At run time the user experience is

runtime error

Looking at the instructions here I am unsure if this is a Dev Express issue or an Entity Framework issue.

Kirsten
  • 15,730
  • 41
  • 179
  • 318

0 Answers0