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;
}
}
}
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();
});
Yes, its in the ApplicationAutoMapperProfile
As you can see in my previous reply, I have added it in the AutoMapperProfile file already and it still isn't working.
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
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