applying an object with a ICollection<Enum> type - asp.net-core

In an ASP.NET 3.1 CORE project, using EF, I am trying to implement an object that holds a type of ICollection<Enum> type.
the problem is after reading some tutorials and trying to migrate it to my database something seems off, I will attach screenshots and code for more understanding.
this is the object class :
public class UsersCredentialsModel
{
[Key]
public string UserId { get; set; }
public ICollection<ServiceModel> Services { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public string Hash { get; set; }
}
The ServiceModel class:
public class ServiceModel
{
[Key]
public string ServiceId { get; set; }
public Service Service { get; set; }
}
The Service Enum Class:
public enum Service : int
{
Badoo = 0,
Tinder = 1,
Grinder = 2,
OkCupid = 3
}
This is the AppDbContext class:
public class AppDbContext : IdentityDbContext<ApplicationUser>
{
public AppDbContext(DbContextOptions<AppDbContext> options) : base(options)
{
}
protected override void OnModelCreating(ModelBuilder builder)
{
builder.Entity<Message>().Property(m => m.Service).HasConversion<int>();
builder.Entity<ApplicationUser>().HasMany<Message>(m => m.Messages).WithOne(u =>
u.User).IsRequired();
builder.Entity<ServiceModel>().Property(m => m.Service).HasConversion<int>();
builder.Entity<UsersCredentialsModel>().HasMany(s => s.Services);
base.OnModelCreating(builder);
}
public DbSet<UsersCredentialsModel> UsersCredentialsModels { get; set; }
public DbSet<ServiceModel> ServiceModel { get; set; }
public DbSet<Message> Messages { get; set; }
public DbSet<CookieModel> CookieModel { get; set; }
public DbSet<ProjectionModel> ProjectionModel { get; set; }
}
This is a picture of the UsersCredentialsModel database schema:
** I believe that there should be a filed called "ServiceId" corresponding to the Id of the second table.
and finally a picture of the ServiceModel schema:
from what I understood you can't implement ICollection of type ENUM and you have to wrap it in a class so basically you need an object to hold the ENUM with an ID and another Id that holds the userId.
The problem is that UserCredentialsModel table should hold an Id property of ServiceId coming from ServiceModel table.
because the class has a field of ICollection but when migrating it does nothing

Related

HasKey: error while using Fluent API to configure which property should be used as the foreign key

I have two classes (Parent, Child) in ASP.Net Core and I'm using code first approach, my real project is more complex than that, so i have to use this method to migrate to database.
The issue here is when I'm defining the relations in Db Context class i face this error noting that I'm following this Microsoft document https://learn.microsoft.com/en-us/ef/core/modeling/relationships, and you can find the main class below:
Error: Cannot implicitly convert type 'System.Collections.Generic.List<logintest.Models.Chlid>' to 'System.Collections.Generic.IEnumerable<logintest.Models.Child>'. An explicit conversion exists (are you missing a cast?)
public class Parent
{
public int Id { get; set; }
public List<Chlid> Childs { get; set; }
}
public class Child
{
public int Id { get; set; }
public int ParentId { get; set; }
public Parent Parent { get; set; }
}
public class AppDbContext : DbContext
{
public DbSet<Parent> Parents { get; set; }
public DbSet<Child> Childs { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Child>()
.HasOne(p => p.Parent)
.WithMany(b => b.Childs)
.HasForeignKey(b => b.ParentId);
}
}

How to use Automapper in ASP.NET Core to create mapping configuration for the following type of hierarchy

I would like to map the following hierarchy of entities to the TestViewModel class. I have TestViewModel class with the same member names and perhaps I will add more members to the view model. I am using AutoMapper.
public class TestProfile : Profile
{
public TestProfile ()
{
CreateMap ??????
}
}
public class Test
{
public List<Test1> Tests1 { get; set; }
public int TestId { get; set; }
}
public class Test1
{
public int Test1Id { get; set; }
public string Name { get; set; }
public List<Document> Documents { get; set; }
}
public class Document
{
public int DocumentId { get; set; }
public DateTimeOffset? ChangeDate { get; set; }
public List<Payload> Payloads { get; set; }
}
public class Payload
{
public string PayloadName { get; set; }
}
You didn't tell us what your TestViewModel class looks like, and whether you also have DocumentViewModel, PayloadViewModel, etc. Typically if you are mapping to a another set of classes that have the same naming and structure, like a set of ViewModels, you will want to have a configuration like this:
public class TestProfile : Profile
{
public TestProfile()
{
CreateMap<Test, TestViewModel>();
CreateMap<Test1, Test1ViewModel>();
CreateMap<Document, DocumentViewModel>();
CreateMap<Payload, PayloadViewModel>();
}
}
This will map all like-named properties between the two sets of classes. If your TestViewModel shares the same child entities, then you only need the first line.

Problem with mapping two objects (with lists)

I am looking for solution my issue... Probably my Shifts class cannot be mapped.
I have entity class Worker:
public class Worker
{
public int Id { get; set; }
[Required]
[MaxLength(50)]
public string Name { get; set; }
[Required]
[MaxLength(50)]
public string LastName { get; set; }
[MaxLength(200)]
public string PhotoFilePath { get; set; }
public Workplace Workplace { get; set; }
public int WorkplaceId { get; set; }
public List<Service> Services { get; set; }
public List<Shift> Shifts { get; set; }
public IEnumerable<Worker> ToList()
{
throw new NotImplementedException();
}
}
And model WorkerModel:
public int Id { get; set; }
[Required]
[DisplayName("Imię")]
public string Name { get; set; }
[DisplayName("Nazwisko")]
public string LastName { get; set; }
[Display(Name = "Zdjęcie")]
public IFormFile Photo { get; set; }
public string PhotoFilePath { get; set; }
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int WorkplaceId { get; set; }
public List<ServiceModel> Services { get; set; }
public List<ShiftModel> Shifts { get; set; }
}
My default mapper profile:
//Mapping workers
CreateMap<Worker, WorkerModel>();
CreateMap<WorkerModel, Worker>();
And when I try map model to entity class in my action:
Worker worker = _mapper.Map<Worker>(model);
I get an issue:
AutoMapperMappingException: Missing type map configuration or unsupported mapping.
This is caused by different mapping types. Take the property Service as an example.
The resource is a type of Service.
But the destination is a type of ServiceModel.
So, they need to be converted. Here is a demo.
I create the Service and ServiceModel according to your model.
public class Service
{
public int serviceID { get; set; }
public string myservice { get; set; }
}
public class ServiceModel
{
public int serviceID { get; set; }
public string myservice { get; set; }
}
This is mapping relationship.
public class AutomapProfile : Profile
{
public AutomapProfile()
{
CreateMap<Worker, WorkerModel>();
CreateMap<WorkerModel, Worker>()
.ForMember(m => m.Services, x => x.MapFrom(y => y.Services.Select(a=>
new Service
{
serviceID=a.serviceID,
myservice=a.myservice
})));
}
}
This is the mapping method.
public IActionResult Index()
{
var model = new WorkerModel
{
Id=1,
Name="names",
//...
Services = new List<ServiceModel>
{
new ServiceModel{ serviceID=1, myservice="service1"},
new ServiceModel{ serviceID=2, myservice="service2"},
},
//...
};
Worker worker = _mapper.Map<Worker>(model);
return Ok(worker);
}
Result.

Automapper maps with wrong property name or I am doing something wrong

I am trying to map my domain entity to DTO. What I am getting in generated query is wrongly concatenated property name.
This is my entity class: (some code is removed for brevity)
public class Product : BaseEntity
{
public int ProductId { get; set; }
public string Name { get; set; }
public virtual EntityUnit EntityUnit { get; set; }
}
This my DTO
public class ProductDto : IMapFrom<Product>
{
public int Id { get; set; }
public string Unit { get; set; }
public void Mapping(Profile profile)
{
profile.CreateMap<Product, ProductDto>()
.ForMember(dest => dest.Name, opt => opt.MapFrom(src => src.EntityUnit.Name));
}
}
This is my EntityUnit class:
public class EntityUnit : BaseEntity
{
public int UnitId { get; set; }
public string Name { get; set; }
}
After all this is the generated query:(on mini-profiler)
Actually that must be p.UnitId instead of EntityUnitUnitId (which works). Automapper version is 9.0
What I am doing wrong here?

Setting up Automapper 5.1

I am having trouble following the wiki in this instance. I wanted to use Automapper 5.2. I cannot find a simple end for end example that shows a solid configuration with context. By context I mean where do you put the config files and whats the difference between static and instance api?
I checked out the DNRTV download but it deals with the 1.0 version.
How do you set this package up? I have a model called Client as below.
public class Client : IEntityBase
{
public Client()
{
Jobs = new List<Job>();
}
public int Id { get; set; }
public int ClientNo { get; set; }
public bool Company { get; set; }
public string CompanyName { get; set; }
public string ClientFirstName { get; set; }
public DateTime DeActivated { get; set; }
public bool Activity { get; set; }
public DateTime DateCreated { get; set; }
public DateTime DateUpdated { get; set; }
public int? StateId { get; set; }
public State State { get; set; }
public int CreatorId { get; set; }
public User Creator { get; set; }
public ICollection<Job> Jobs { get; set; }
}
and a ClientViewModel as so:
public class ClientViewModel
{
public int Id { get; set; }
public int ClientNo { get; set; }
public bool Company { get; set; }
public string CompanyName { get; set; }
public string ClientFirstName { get; set; }
public DateTime DeActivated { get; set; }
public bool Activity { get; set; }
public DateTime DateCreated { get; set; }
public DateTime DateUpdated { get; set; }
public int? StateId { get; set; }
public int CreatorId { get; set; }
public int[] Jobs { get; set; }
}
I am unsure how to set AutoMapper up with regard to configuration. That is, they talk about a global.asax file and I am using aspnet core.. there is no Global.asax file..
What do you put in the Startup.cs file if anything.
Given these two files above what do I need to do to use Automapper with them?
Regards
Here is the steps to configure the automapper in asp.net core mvc.
1. Create the mapping profile class which extends from Profile
public class ClientMappingProfile : Profile
{
public ClientMappingProfile ()
{
CreateMap<Client, ClientViewModel>().ReverseMap();
}
}
2. Create the AutoMapper Configuration Class and add your mapping profile class here.
public class AutoMapperConfiguration
{
public MapperConfiguration Configure()
{
var config = new MapperConfiguration(cfg =>
{
cfg.AddProfile<ClientMappingProfile>();
});
return config;
}
}
3. Create extension method so, we can add this to Startup.cs ConfigureServices method
public static class CustomMvcServiceCollectionExtensions
{
public static void AddAutoMapper(this IServiceCollection services)
{
if (services == null)
{
throw new ArgumentNullException(nameof(services));
}
var config = new AutoMapperConfiguration().Configure();
services.AddSingleton<IMapper>(sp => config.CreateMapper());
}
}
4. Call the extension method in Startup.cs ConfigureServices method
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<DBContext>(options =>options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddMvc();
services.AddAutoMapper();
}