When adding the user as a navigation property via the abp suite, there is always a build error pre add-migration.
* Severity Code Description Project File Line Suppression State Suppression State Error CS0246 The type or namespace name 'AppUserDto' could not be found (are you missing a using directive or an assembly reference?) VideoMarking.Application.Contracts \aspnet-core\src\VideoMarking.Application.Contracts\Notes\NoteWithNavigationPropertiesDto.cs 12 Active
If we manually add the AppUserDto, the build error goes but when we manually run add-migration it errors with:
The property 'AppUser.ExtraProperties' could not be mapped, because it is of type 'Dictionary<string, object>' 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'.
The AppUserDto looks like this:
public class AppUserDto : FullAuditedEntityDto<Guid>
{
public Guid? TenantId { get; private set; }
public string UserName { get; private set; }
public string Name { get; private set; }
public string Surname { get; private set; }
public string Email { get; private set; }
public bool EmailConfirmed { get; private set; }
public string PhoneNumber { get; private set; }
public bool PhoneNumberConfirmed { get; private set; }
public bool SEN { get; set; }
public bool PupilPremium { get; set; }
public bool EAL { get; set; }
public bool ChildInCare { get; set; }
public DateTime DateOfBirth { get; set; }
}
We have tried adding b.ConfigureExtraProperties();
to the model builder in the dbcontext to no effect as suggested here: https://github.com/abpframework/abp/issues/1517
We have not been able to find a solution to this issue and we require the ability to link numerous entities to the user table.
Please can someone advise the proper way to achieve this.
Thanks
- ABP Framework version: v3
- UI type: Angular
- Tiered (MVC) or Identity Server Seperated (Angular): no
17 Answer(s)
-
0
you need to ignore ExtraProperties like this;
CreateMap<AppUser, AppUserDto>().Ignore(x => x.ExtraProperties);
check out the following question, similar one https://support.abp.io/QA/Questions/150/How-To-Create-a-Help-Desk-Ticket-Entity#answer-21da8121-ab88-ab2c-67f0-39f51d1b1819
-
0
Hi @Alper,
Thanks for the response. I've added that line now, and followed step by step using the example given with the suite, but I am still getting the error
`The property 'AppUser.ExtraProperties' could not be mapped, because it is of type 'Dictionary<string, object>' 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'` on add-migration.
The relevant section of my AutoMapperProfile file looks like:
CreateMap<AppUser, AppUserDto>().Ignore(x => x.ExtraProperties); CreateMap<NoteCreateDto, Note>().IgnoreFullAuditedObjectProperties().Ignore(x => x.Id).Ignore(x => x.TenantId); CreateMap<NoteUpdateDto, Note>().IgnoreFullAuditedObjectProperties().Ignore(x => x.Id).Ignore(x => x.TenantId); CreateMap<Note, NoteDto>(); CreateMap<NoteWithNavigationProperties, NoteWithNavigationPropertiesDto>(); CreateMap<AppUser, LookupDto<Guid?>>().ForMember(dest => dest.DisplayName, opt => opt.MapFrom(src => src.Name));
Please can you advise, Kitty
-
0
you need to add the below line in
BookStoreApplicationAutoMapperProfile.cs
CreateMap<AppUser, AppUserDto>().Ignore(x => x.ExtraProperties);
-
0
As you can see in my previous reply, I have added it in the AutoMapperProfile file already and it still isn't working.
-
0
kitty, there are multiple AutoMapperProfile classes. I just want to ensure that you have added it in the correct project.
-
0
Yes, its in the ApplicationAutoMapperProfile
-
0
Can you share the AppUser entity? And also the code piece which you add it to ModelBuilder in *DbContextModelCreatingExtensions.cs?
Normally, using ConfigureByConvention should fix this.
Example:
builder.Entity<IdentityUser>(b => { b.ToTable(options.TablePrefix + "AppUsers", options.Schema); . . . b.ConfigureByConvention(); . . . }
-
0
Hi,
The AppUser entity looks like:
public class AppUser : FullAuditedAggregateRoot<Guid>, IUser { #region Base properties /* These properties are shared with the IdentityUser entity of the Identity module. * Do not change these properties through this class. Instead, use Identity module * services (like IdentityUserManager) to change them. * So, this properties are designed as read only! */ public virtual Guid? TenantId { get; private set; } public virtual string UserName { get; private set; } public virtual string Name { get; private set; } public virtual string Surname { get; private set; } public virtual string Email { get; private set; } public virtual bool EmailConfirmed { get; private set; } public virtual string PhoneNumber { get; private set; } public virtual bool PhoneNumberConfirmed { get; private set; } #endregion public virtual bool SEN { get; set; } public virtual bool PupilPremium { get; set; } public virtual bool EAL { get; set; } public virtual bool ChildInCare { get; set; } public virtual DateTime DateOfBirth { get; set; } [ForeignKey("School")] public Guid? SchoolId { get; set; } public virtual School School { get; set; } [ForeignKey("Address")] public Guid? AddressId { get; set; } public virtual Address Address { get; set; } [ForeignKey("SchoolYear")] public Guid? SchoolYearId { get; set; } public virtual SchoolYear SchoolYear { get; set; } /* Add your own properties here. Example: * * public virtual string MyProperty { get; set; } * public string MyProperty { get; set; } * * If you add a property and using the EF Core, remember these; * * 1. update VideoMarkingDbContext.OnModelCreating * to configure the mapping for your new property * 2. Update VideoMarkingEfCoreEntityExtensionMappings to extend the IdentityUser entity * and add your new property to the migration. * 3. Use the Add-Migration to add a new database migration. * 4. Run the .DbMigrator project (or use the Update-Database command) to apply * schema change to the database. */ private AppUser() { }
The OnModelCreating() method looks like:
protected override void OnModelCreating(ModelBuilder builder) { base.OnModelCreating(builder); /* Configure the shared tables (with included modules) here */ builder.Entity<AppUser>(b => { b.ToTable(AbpIdentityDbProperties.DbTablePrefix + "Users"); //Sharing the same table "AbpUsers" with the IdentityUser b.Property(p => p.DateOfBirth); b.Property(p => p.SEN); b.Property(p => p.ChildInCare); b.Property(p => p.PupilPremium); b.Property(p => p.EAL); b.ConfigureByConvention(); b.ConfigureAbpUser(); /* Configure mappings for your additional properties. * Also see the VideoMarkingEfCoreEntityExtensionMappings class. */ }); /* Configure your own tables/entities inside the ConfigureVideoMarking method */ builder.ConfigureVideoMarking(); }
The Notes section in DbContextModelCreatingExtensions:
builder.Entity<Note>(b => { b.ToTable(VideoMarkingConsts.DbTablePrefix + "Notes", VideoMarkingConsts.DbSchema); b.ConfigureByConvention(); b.Property(x => x.TenantId).HasColumnName(nameof(Note.TenantId)); b.Property(x => x.Message).HasColumnName(nameof(Note.Message)).IsRequired(); });
-
0
Don't use navigation properties to other aggregate roots. See https://github.com/abpframework/abp/issues/1517
-
0
Note is not an aggregate root, it's a FullAuditedEntity. We need to be able to link user to it. Please can you advise on how we need to actually implement this.
using VideoMarking.Users; using System; using Volo.Abp.Domain.Entities; using Volo.Abp.Domain.Entities.Auditing; using Volo.Abp.MultiTenancy; using JetBrains.Annotations; using Volo.Abp; namespace VideoMarking.Notes { public class Note : FullAuditedEntity<Guid>, IMultiTenant { public virtual Guid? TenantId { get; set; } [NotNull] public virtual string Message { get; set; } public Guid? AppUserId { get; set; } public AppUser AppUser { get; set; } public Note() { } public Note(Guid id, string message) { Id = id; Check.NotNull(message, nameof(message)); Message = message; } } }
-
0
@KittyJuggins , remove AppUser from Note and keep the AppUserId only. When you fetch Note from database, fetch the user in a seperate query . Then map the both to your DTO. This is the best practise
-
1
Hey all, I have been following this thread and several similar to it for a while to try and solve the issue I am having of adding a Navigation Property to a User. I must be missing something really simple because no matter what I try I cannot get it to work. I decided to start from scratch with a blank project and take a screen recording of it to upload in hopes you can point out where I am going wrong. And hopefully this helps out everyone else with the issue.
Here is the video. https://www.youtube.com/watch?v=i1VH8B06njs
Started from scratch with ABP Suite
- Created an Entity called "Note"
- Added a property called Title
- Generated
- Rebuilt web project to ensure it worked
- Added a DTO class
- Added CreateMap and ignored the ExtraProperties
- Added navigation property via ABP Suite for a User based on the screnshots provided HERE
- Generated updates
- Tweaked a couple of Menu related issues due to regeneration
- Ran generation again and this is where the Extra Properties mapping issues comes in
Not seen in the video is the suggestion of removing public AppUser AppUser { get; set; } from the Notes class. I do this, but it gets added back on while generating, which makes sense. I have only ever tried creating an Entity as a FullAuditedAggregateRoot because I want all the properties and features that come along with that. But I can see the OP states that this issue still persists even with a FullAuditedEntity.
-
0
hi myke@mycra.co I just made a sample project for this topic. See https://community.abp.io/articles/how-to-add-the-user-entity-as-a-navigation-property-furp75ex
Note this example is implemented with ABP Commercial 3.1.0-rc.3. This is a RC version. If you want to install the CLI and Suite RC version follow the next steps:
1- Uninstall the current version of the CLI and install the specific RC version:
dotnet tool uninstall --global Volo.Abp.Cli && dotnet tool install --global Volo.Abp.Cli --version 3.1.0-rc.3
2- Uninstall the current version of the Suite and install the specific RC version:
dotnet tool uninstall --global Volo.Abp.Suite && dotnet tool install -g Volo.Abp.Suite --version 3.1.0-rc.3 --add-source https://nuget.abp.io/<YOUR-API-KEY>/v3/index.json
Don't forget to replace the
<YOUR-API-KEY>
with your own key! -
0
I appreciate you putting up an article about this! Is the source code located somewhere for that?
I went through the steps outlined again(which mirrored the steps I have tried previously) and I end up with the same error as always 😞 Could it be my ABP Commercial version? I am running 3.0.5 on .NET Core 3.1 on macOS.
-
0
I guess it's related a fix that's done in v3.1.0 (because we fixed some Suite issues in 3.1.0) Today we have released a new RC version (preview) of 3.1.0 - RC4 (the production of 3.1.0 will be released this weekend) Try to create a new project with 3.1.0-RC4 and we'll see if it's related with MAC or the framework.
-
0
Success!!! Updated to the 3.1.0 release from today and this now works as expected. Screen Shot 2020-09-04 at 6.21.53 PM.png
-
0
super! closing this