Starts in:
2 DAYS
0 HR
50 MIN
33 SEC
Starts in:
2 D
0 H
50 M
33 S
Open Closed

Migration 4.2.1 to 4.3: error when regenerate entities with navigation properties AppUserId #1343


User avatar
0
christophe.baille created
  • ABP Framework version: v4.3.0
  • UI type: Angular
  • DB provider: EF Core
  • Tiered (MVC) or Identity Server Separated (Angular): no
  • Exception message and stack trace: The property 'AppUser.ExtraProperties' could not be mapped because it is of type 'ExtraPropertyDictionary', which is not a supported primitive type or a valid entity type. Either explicitly map this property, or ignore it using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.

I started to migrate a soution from 4.21 to 4.3, then I did notice that when I regenerate entities of my solution, it was creating index and FK to my navigation properties. As it is a good improvement I wanted to regenerate all entities.

It works well for all my entites except the one which have Navigation properties "AppUserId".

I got a long error message (see attachment bellow), the most important seems this:

The property 'AppUser.ExtraProperties' could not be mapped because it is of type 'ExtraPropertyDictionary', which is not a supported primitive type or a valid entity type. Either explicitly map this property, or ignore it using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.

I see this line added on MyProjectDbContextModelCreatingExtensions, into builder.Entity<MyExistingEntity>

b.HasOne<AppUser>().WithMany().HasForeignKey(x => x.AppUserId);

I see some posts about it: https://github.com/abpframework/abp/issues/927 https://github.com/abpframework/abp/issues/1414 https://github.com/abpframework/abp/issues/1517 https://github.com/abpframework/abp/issues/2746

But YourDbContextModelCreatingExtensions.cs is modified by ABP suite just before trying to "generate" my migration script, so I can not test the suggestions

I did some tests and noticed that the error is coming from this line

NOTE: I put a comment to a similar question (without mentionning that it is realted to the update), as it is open since 2 weeks and still not assigned, I post it here.

https://support.abp.io/QA/Questions/1263/abp-suite---AppUser-as-navigation-property-is-not-working

Thanks for your help.


28 Answer(s)
  • User Avatar
    0
    alper created
    Support Team Director

    seems like duplicate of https://support.abp.io/QA/Questions/1263/abp-suite---AppUser-as-navigation-property-is-not-working

  • User Avatar
    0
    christophe.baille created

    Yes, I was wondering. However they do not mention if it is when running the app or the generated migration script or when the are "building" the entity (which generate the migration script

    Following your links I tried:

    https://support.abp.io/QA/Questions/1280/The-property-'OrganizationUnitExtraProperties'-could-not-be-mapped-because I added b.ConfigureExtraProperties(); b.ConfigureByConvention(); //This one was already on the code In the method OnModelCreating, into builder.Entity<AppUser> It does not work. I am not 100% sure if I should add this on AppUer or on myEntity. I can not add ConfigureExtraProperties on myEntity, forst because it does not exists for my entity, plus ConfigureMyApp is regenerated when rebuild my entity, so i can not do changes on it

    https://support.abp.io/QA/Questions/1271/Add-relation-between-AbpUser-to-My-Table I added builder.ConfigureIdentityPro(); Into ConfigureMyProject method, I then added it into OnModelCreating as it was not working Not working neither

    https://github.com/abpframework/abp/issues/8019 About this, not sure I am concerned as I have error even before my migration file get generated.

    I will keep doing some tests through information I get from your links though, but I would appreciate some more help as I am not sure to find out the issue.

    Thanks

  • User Avatar
    0
    alper created
    Support Team Director

    we are also checking

  • User Avatar
    0
    christophe.baille created

    Any update about it?

  • User Avatar
    0
    christophe.baille created

    Is there anyone following this ticket? I am stuck on my migration since about 10 days now and I still have no clue on how or when I will complete it...

    Thank you

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Hi,

    In appUser case, you need change the YourDbContextModelCreatingExtensions alfter suite added navigation properties.

    1. Remove b.HasOne<AppUser>().WithMany().HasForeignKey(x => x.AppUserId); in YourDbContextModelCreatingExtensions.
    2. Open *MigrationsDbContext, add the following code in the OnModelCreating method:
    builder.Entity<MyExistingEntity>(b =>
    {
        b.Ignore(x => x.AppUser);
        
        b.HasOne<IdentityUser>().WithMany().HasForeignKey(nameof(MyExistingEntity.AppUserId)).IsRequired(false);
    });
    
    builder.Entity<IdentityUser>(b =>
    {
        b.Property<Guid?>(nameof(AppUser.MyExistingEntityId));
        b.HasOne<MyExistingEntity>().WithMany().HasForeignKey(nameof(AppUser.MyExistingEntityId));
    });
    
    1. Open *DbContext, add the following code in the OnModelCreating method:
    builder.Entity<AppUser>(b =>
    {
        b.ToTable(AbpIdentityDbProperties.DbTablePrefix + "Users"); //Sharing the same table "AbpUsers" with the IdentityUser
    
        b.ConfigureByConvention();
        b.ConfigureAbpUser();
    
        /* Configure mappings for your additional properties
         * Also see the CustomApplicationModulesEfCoreEntityExtensionMappings class
         */
    
        b.Property<Guid?>(nameof(AppUser.MyExistingEntityId));
        b.HasOne<MyExistingEntity>().WithMany().HasForeignKey(nameof(AppUser.MyExistingEntityId));
    });
    
    /* Configure your own tables/entities inside the ConfigureCustomApplicationModules method */
    
    builder.ConfigureCustomApplicationModules();
    
    builder.Entity<MyExistingEntity>(b =>
    {
        //SET RELATIONS FOR THE PROJECT DBCONTEXT
    
        b.HasOne(x => x.AppUser).WithMany().HasForeignKey(nameof(MyExistingEntity.AppUserId)).IsRequired(false);
    });
    

    Re-create migration files.

  • User Avatar
    0
    christophe.baille created

    I tried your changes but several parts were wrong on the code, I then changed like this:

    1- Remove b.HasOne<AppUser>().WithMany().HasForeignKey(x => x.AppUserId); in YourDbContextModelCreatingExtensions. → OK

    2- Open *MigrationsDbContext, add the following code in the OnModelCreating method:

    b.Ignore(x => x.AppUser); //Replace by AppUserId as AppUser does not exists

    builder.Entity<IdentityUser>(b => { b.Property<Guid?>(nameof(AppUser.MyExistingEntityId)); //Replace by Id as MyExistingEntityId does not exists b.HasOne<MyExistingEntity>().WithMany().HasForeignKey(nameof(AppUser.MyExistingEntityId)); //Replace by Id as MyExistingEntityId does not exists });

    3- Open *DbContext, add the following code in the OnModelCreating method:

    b.Property<Guid?>(nameof(AppUser.OrganizationId)); //Replace by Id as OrganizationId does not exists

    b.HasOne<MyExistingEntity>().WithMany().HasForeignKey(nameof(AppUser.MyExistingEntityId)); //Replace by Id as MyExistingEntityId does not exists

    builder.ConfigureCustomApplicationModules(); // Commented it as I do not have this method I have this instead, but seems the same: builder.ConfigureMyApp();

    I guess all the part builder.Entity<Test> was for test? I did try to add it but I do not know what to put to make it working...

    After making this changes I then try to create migration files but I got this error:

    The property 'Id' cannot be added to type 'IdentityUser' because the type of the corresponding CLR property or field 'string' does not match the specified type 'Nullable<Guid>'

    Please keep me updated, I am available for remote connection, it might be faster to solve this than the way we do actually.

    Thanks

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Replace by Id as AppUserId does not exists, Replace by Id as MyExistingEntityId does not exists

    You should not do this, AppUserId and MyExistingEntityId are foreign key(base entity relationship).

    See : https://docs.microsoft.com/en-us/ef/core/modeling/relationships?tabs=fluent-api,fluent-api-simple-key,simple-key#fully-defined-relationships

    Your entity should be:

    One to one relationship

    public class AppUser : .....
    {
       public Guid MyExistingEntityId {get;set;}
       public MyExistingEntity MyExistingEntity {get;set;}
    }
    
    public class MyExistingEntity : ....
    {
       public Guid AppUserId {get;set;}
       public AppUser AppUser {get;set;}
    }
    

    One to many relationship

    public class AppUser : .....
    {
       public List<MyExistingEntity> MyExistingEntities {get;set;}
    }
    
    public class MyExistingEntity : ....
    {
       public Guid AppUserId {get;set;}
       public AppUser AppUser {get;set;}
    }
    

    I am available for remote connection, it might be faster to solve this than the way we do actually

    Ok, we can. shiwei.liang@volosoft.com

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Hi,

    Try:

    public class AppUser : ...
    {
      public ExistProfile ExistProfile {get;set}
    }
    
    public class ExistProfile : ...
    {
       public Guid AppUserId {get;set;}
       public AppUser AppUser {get;set;}
    }
    

    MigrationsDbContext

    builder.Entity<ExistProfile>(b =>
    {
        b.Ignore(x => x.AppUser);
        b.HasOne<IdentityUser>().WithOne().HasForeignKey<ExistProfile>(x => x.AppUserId);
    });
    

    DbContext

    builder.Entity<ExistProfile>(b =>
    {
        b.HasOne(x => x.AppUser).WithOne(x => x.ExistProfile).HasForeignKey<ExistProfile>(x => x.AppUserId);
    });
    
  • User Avatar
    0
    christophe.baille created

    With this, I got this error:

    The relationship from 'StaffProfile' to 'IdentityUser' with foreign key properties {'AppUserId' : Nullable<Guid>} cannot target the primary key {'Id' : string} because it is not compatible. Configure a principal key or a set of compatible foreign key properties for this relationship.

    So I tested by creating another field for the primary key in my ExistProfile entity:

    public string AppUserIdString { get; set; }

    It then generate a script but it is not what I want:

    • it create a new column, I want to keep AppUserId as it is in production already, i can not change the type. Plus if I want to change the type, I need to change a lot of code

    • the script create a new table IdentityUser, we are actually using ABPUser table, we can not use another.

  • User Avatar
    2
    christophe.baille created

    Issue resolved.

    After getting the error, everything is generated (UI, back-end) appart of the migration of the migration file.

    To go further, some changes need to be done on our code:

    1- *DbContextModelCreatingExtensions.cs file:

    From the entity you generated, delete this line:

    b.HasOne<AppUser>().WithMany().HasForeignKey(x => x.AppUserId);
    

    2- On EntityGenerated.cs, add:

    public AppUser AppUser { get; set; }
    

    3- On AppUser.cs, add:

    public EntityGenerated EntityGenerated { get; set; }
    

    4- On OnModelCreating method of *MigrationDbContext.cs, add:

                builder.Entity<EntityGenerated >(b =>
                {
                    b.Ignore(x => x.AppUser);
                        b.HasOne<IdentityUser>().WithOne().HasForeignKey<EntityGenerated >(x => x.AppUserId);
                });
    

    NOTE: Be very careful to use Volo.Abp.Identity.IdentityUser for IdentityUser, by using Microsoft.AspNetCore.Identity.IdentityUser it will not work

    5- On OnModelCreating method of *DbContext.cs, add:

                builder.Entity<EntityGenerated>(b =>
                {
                        b.HasOne(x => x.AppUser).WithOne(x => x.EntityGenerated).HasForeignKey<EntityGenerated>(x => x.AppUserId);
                });
    

    Once everything is done, you can now generate the migration script and update the database.

    Thanks again Liangshiwei for your support

  • User Avatar
    0
    christophe.baille created

    Hi upgraded to version 4.4 and still have to delete this line manually to make my solution working after regenerating my entity.

    b.HasOne<AppUser>().WithMany().HasForeignKey(x => x.AppUserId);

    Any plan/schedule to fix this issue from ABP Framework?

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Hi,

    In 4.4 , we have remove the DbMigrations project, it will make add navigation properties be easy.

    You can refer the document: https://community.abp.io/articles/unifying-dbcontexts-for-ef-core-removing-the-ef-core-migrations-project-nsyhrtna

  • User Avatar
    0
    christophe.baille created

    Thanks I did notice that. However I saw a warning about having some errors using ABP Suite code generation, asking to wait next version. I asked, which version we need to wait?

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Hi,

    You can do it, it It is available now.

  • User Avatar
    0
    christophe.baille created

    Thanks, I will try it then

  • User Avatar
    0
    christophe.baille created

    There is one point I don't really understand on how to do: Remove AppUser Entity

    If I have to remove the class AppUser.cs from Domain project, what should I put on my navigation property AppUserId?

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Use IdentityUser replace AppUser.

  • User Avatar
    0
    christophe.baille created

    Thanks.

    As there is no entity named IdentityUser on the entity list,

    and there is no file neither

    I am filling values manually.

    namespace: Volo.Abp.Identity EntityName: IdentityUser DtoName: IdentityUserDto

    I will keep Property name AppUserId for now, so it will not change the field on my tables.

    Collection name: Users

    In my AppDbContext, I will replace:

    public DbSet<AppUser> Users { get; set; } by public DbSet<IdentityUser> Users { get; set; }

    I did replace AppUser by IdentityUser on my solution to have the project building without any errors.

    But now I have this error when try to generate my entity. I already deleted EntityFramework.DbMigration and updated the references as explained on the document.

  • User Avatar
    0
    christophe.baille created

    To fix the previous issue, I removed the project from ABP Suite (1), then I added it again (2)

    Now I have a different error:

    I am supposed to have only one DbContext as I removed this MigrationDbContext right? Or there is something I didn't understand?

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Hi,

    You can remove the abp suite cache and try again.

    C:\Users\<username>\.abp\suite

  • User Avatar
    0
    christophe.baille created

    Still the same

  • User Avatar
    0
    christophe.baille created

    I don't understand on why it is still looking for this MigrationDbContext, I didn't declare it anymore on my solution

  • User Avatar
    0
    christophe.baille created

    I tried with a new solution and do not have this issue to generate a new entity it works well. For my existing solution, could this DbContext name asked be stored somewhere on the database?

  • User Avatar
    0
    liangshiwei created
    Support Team Fullstack Developer

    Can I check it remotely? shiwei.liang@volosoft.com

Made with ❤️ on ABP v9.1.0-preview. Updated on November 20, 2024, 13:06