Database model for users with multiple capabilities - asp.net

In another question, I explain my goal to create 2 different types of users with different capabilities in my ASP.Net MVC 5 website. I wonder how I would be able to modify my current database models to hold the related information based on their type. My current models are as follows:
public class User : IUser
{
public User()
: this(String.Empty)
{
}
public User(string userName)
{
UserName = userName;
Id = Guid.NewGuid().ToString();
}
[Key]
public string Id { get; set; }
[Required]
public string UserName { get; set; }
[Required]
public string FirstName { get; set; }
[Required]
public string LastName { get; set; }
public string Phone { get; set; }
public string MobilePhone { get; set; }
[Required]
[DataType(DataType.EmailAddress)]
public string Email { get; set; }
public virtual IList<UserAddress> Addresses { get; set; }
}
public class Restaurant
{
[Key]
public int ID { get; set; }
[Required]
public string Name { get; set; }
public virtual IList<RestaurantAddress> Addresses { get; set; }
public virtual IList<RestaurantFood> Menu { get; set; }
public virtual IList<Review> Reviews { get; set; }
[DataType(DataType.Url)]
public string Website { get; set; }
[DataType(DataType.PhoneNumber)]
public string Phone { get; set; }
[DataType(DataType.PhoneNumber)]
public string Fax { get; set; }
[DataType(DataType.EmailAddress)]
public string Email { get; set; }
public int Seats { get; set; }
public double AverageRating { get; set; }
public double AveragePrice { get; set; }
}
One solution that comes to my mind is to move the additional info of the User class to another class and hold the foreign key for the related model in the basic user info class. Something like:
public class User : IUser
{
public User()
: this(String.Empty)
{
}
public User(string userName)
{
UserName = userName;
Id = Guid.NewGuid().ToString();
}
[Key]
public string Id { get; set; }
[Required]
public string UserName { get; set; }
public virtual ExtendedUser NormalUserInfo { get; set; }
public virtual Restaurant RestaurantInfo { get; set; }
}
public class ExtendedUser
{
[Required]
public string FirstName { get; set; }
[Required]
public string LastName { get; set; }
public string Phone { get; set; }
public string MobilePhone { get; set; }
[Required]
[DataType(DataType.EmailAddress)]
public string Email { get; set; }
public virtual IList<UserAddress> Addresses { get; set; }
}
public class Restaurant
{
[Key]
public int ID { get; set; }
[Required]
public string Name { get; set; }
public virtual IList<RestaurantAddress> Addresses { get; set; }
public virtual IList<RestaurantFood> Menu { get; set; }
public virtual IList<Review> Reviews { get; set; }
[DataType(DataType.Url)]
public string Website { get; set; }
[DataType(DataType.PhoneNumber)]
public string Phone { get; set; }
[DataType(DataType.PhoneNumber)]
public string Fax { get; set; }
[DataType(DataType.EmailAddress)]
public string Email { get; set; }
public int Seats { get; set; }
public double AverageRating { get; set; }
public double AveragePrice { get; set; }
}
and in controller:
User user = BuildUser();
ExtendedUser normal = BuildNormalUser();
Restaurant rest = BuildRestaurant();
if (model.Type == UserType.NormalUser)
user.NormalUserInfo = normal;
else
user.RestaurantInfo = normal;
However, I'm not sure that this is the right thing to do.

Related

How to make DTOs for complex models

My target with the below mentioned classes is to make one DTOs class out of these classes and register AppUser in sqlite database. I use Identity core. I thank you for every body who has given me help on solving this problem.
By the way: is that possible to have virutal properties inside DTO classes? Other thing which i am struggling with is on how to handle the incoming user input (in this case DTO). I get the following error time and again Cannot implicitly convert type int to Backend.Data.Gender. I Cannot implicitly convert type Backend.Data.Work_Experience to System.Collections.Generic.List<Backend.Data.Work_Experience>
public class AppUser : IdentityUser<int>
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Description { get; set; }
virtual public Gender Gender { get; set; }
virtual public ICollection<Interest> Interests {get; set;}
virtual public List<Education> Education { get; set; }
virtual public List<Work_Experience> Work_Experiences { get; set; }
virtual public List<Answer> Answers { get; set; }
}
public class Interest
{
[Key]
public int Id { get; set; }
public string InterestName{ get; set; }
public virtual ICollection<AppUser> Users { get; set; }
}
public class Education
{
[Key]
public int EducationsId { get; set; }
public string SchoolName { get; set; }
public string Field_Of_Study { get; set; }
public string StudyPath { get; set; }
public DateTime StartDate { get; set; }
public DateTime EndDate { get; set; }
public int DegreeId { get; set; }
public virtual Degree Degree { get; set; }
public int UserId { get; set; }
public virtual AppUser User { get; set; }
}
public class Degree
{
[Key]
public int DegreesId { get; set; }
public string DegreeName { get; set; }
}
public class Gender
{
[Key]
public int GenderId { get; set; }
public string GenderName { get; set; }
}
public class Work_Experience
{
[Key]
public int WorkExperiencesId { get; set; }
public string JobTitle { get; set; }
public string CompanyName { get; set; }
public string Industry { get; set; }
public string Field_Of_Work { get; set; }
public int UserId { get; set; }
public virtual AppUser User { get; set; }
}
public class Question
{
[Key]
public int QuestionsId { get; set; }
public string Question_text { get; set; }
}
public class Answer
{
[Key]
public int AnswersId { get; set; }
public string Answer_text { get; set; }
public int QuestionId { get; set; }
public virtual Question Question { get; set; }
public int UserId { get; set; }
public virtual AppUser User { get; set; }
}

The entity type 'Customer' cannot be mapped to a table because it is derived from 'ApplicationUser'

I am trying to use separate identity classes that inherit from ApplicationUser, and create a relationship between them. Business and Customer where a Business can have many Customers. I get an error when adding relationships. What is the proper way to achieve adding identity between classes with relationships?
ApplicationUser.cs
public class ApplicationUser : IdentityUser
{
public virtual Business Business { get; set; }
public virtual Customer Customer { get; set; }
[Required]
[Display(Name = "First Name")]
public string FirstName { get; set; }
[Required]
[Display(Name = "Last Name")]
public string LastName { get; set; }
}
Business.cs
public class Business : ApplicationUser
{
public string BusinessUserId { get; set; }
[Required]
public string BusinessName { get; set; }
[Required]
[Display(Name = "Address")]
public string Address { get; set; }
public ICollection<Customer> Customers { get; set; }
....
}
Customer.cs
public class Customer : ApplicationUser
{
public string CustomerUserId { get; set; }
public override Business Business { get; set; }
}
You are using TPH which will go into the same table(AspNetUser) for your above entities.
To use TPT, you could configure models like
public class ApplicationUser : IdentityUser
{
public string BusinessId { get; set; }
[ForeignKey("BusinessId")]
public virtual Business Business { get; set; }
public string CustomerId { get; set; }
[ForeignKey("CustomerId")]
public virtual Customer Customer { get; set; }
[Required]
[Display(Name = "First Name")]
public string FirstName { get; set; }
[Required]
[Display(Name = "Last Name")]
public string LastName { get; set; }
}
public class Business
{
[Key]
public string BusinessUserId { get; set; }
[Required]
public string BusinessName { get; set; }
[Required]
[Display(Name = "Address")]
public string Address { get; set; }
public virtual ApplicationUser User { get; set; }
public ICollection<Customer> Customers { get; set; }
}
public class Customer
{
[Key]
public string CustomerUserId { get; set; }
public string BusinessId { get; set; }
[ForeignKey("BusinessId")]
public Business Business { get; set; }
public virtual ApplicationUser User { get; set; }
}
DbContext:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
public DbSet<Customer> Customers { get; set; }
public DbSet<Business> Businesses { get; set; }
}

automapping 1:1 mvc unmapped members found

I am trying to use automapper to map between my entites db class and my view model. They have the same exact prop names but i get the error thrown saying unmapped members found. From what I understand if you have 1:1 Relationship you do not have to do the manual mapping in the config file. what am I missing here?
product class
public class product
{
public int id { get; set; }
public string sku { get; set; }
public string ISBN { get; set; }
public string itemName { get; set; }
public int numberCds { get; set; }
public string description { get; set; }
public string category { get; set; }
public double price { get; set; }
public double weight { get; set; }
public int stock { get; set; }
public int stockAlert { get; set; }
public string salesTax { get; set; }
public string imgURL { get; set; }
public string videoURL { get; set; }
public int views { get; set; }
public string instantDownload { get; set; }
public string downloadLink { get; set; }
public int active { get; set; }
public string addedBy { get; set; }
public DateTime addedTime { get; set; }
public string updatedBy { get; set; }
public DateTime updatedTime { get; set; }
}
entites class
public partial class newProduct
{
public int id { get; set; }
public string sku { get; set; }
public string ISBN { get; set; }
public string itemName { get; set; }
public Nullable<int> numberCds { get; set; }
public string description { get; set; }
public string category { get; set; }
public double price { get; set; }
public Nullable<double> weight { get; set; }
public Nullable<int> stock { get; set; }
public Nullable<int> stockAlert { get; set; }
public string salesTax { get; set; }
public string imgURL { get; set; }
public string videoURL { get; set; }
public Nullable<int> views { get; set; }
public string instantDownload { get; set; }
public string downloadLink { get; set; }
public int active { get; set; }
public string addedBy { get; set; }
public Nullable<System.DateTime> addedTime { get; set; }
public string updatedBy { get; set; }
public Nullable<System.DateTime> updatedTime { get; set; }
}
Mapping Config
public static void RegisterMaps()
{
AutoMapper.Mapper.Initialize(config =>
{
config.CreateMap<product, newProduct>();
config.CreateMap<newProduct, product>();
});
}
and the controller
public ActionResult Index()
{
using (StoreEntities db = new StoreEntities())
{
var results = (from p in db.newProducts select p).Where(a => a.active == 1);
var products = AutoMapper.Mapper.Map<product>(results);
return View(products);
}

Mapping existing database with code first approch

I have implemented asp .net application without Code first approach. now i want to build different system with existing database and code first.
public class EmployeeEntity
{
public int Id { get; set; }
public string ResourceCode { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime DateOfBirth { get; set; }
public int Gender { get; set; }
public int Status { get; set; }
public string NIC { get; set; }
}
now i want to add code first entities.
[Table("ExternalApplicantEntity")]
public class ExternalApplicantEntity
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ApplicantID { get; set; }
//[ForeignKey("EmployeeEntity")]
//public int Created_By { get; set; }
//public virtual EmployeeEntity EmployeeEntity { get; set; }
public string NIC { get; set; }
public string Mobile { get; set; }
public string Institute { get; set; }
how i combine these codes?

Entity Framework Code First Foreign Key different column key

So, Addresses has a PK of Id and a foreign key of EntityKey which references the Vendors table's Id, because Vendors have Addresses for their physical buildings.
When I query Vendors, I'm not able to return an associated Address.
Note: I don't want to change the schema.
[Table("EE.Address")]
public partial class Address {
[Key]
public Guid Id { get; set; }
[StringLength(50)]
public string Address1 { get; set; }
[StringLength(50)]
public string Address2 { get; set; }
[StringLength(50)]
public string City { get; set; }
[StringLength(5)]
public string State { get; set; }
[StringLength(30)]
public string PostalCode { get; set; }
[StringLength(10)]
public string CountryCode { get; set; }
public Guid EntityKey { get; set; }
[ForeignKey("EntityKey")]
public virtual Vendor Vendor { get; set; }
// EntityKey should be Vendor.Id
}
[Table("EE.Vendor")]
public partial class Vendor {
[Key]
public Guid Id { get; set; }
[StringLength(50)]
public string Name { get; set; }
[StringLength(50)]
public string AlternativeName { get; set; }
[StringLength(50)]
public string VendorCode { get; set; }
[StringLength(50)]
public string TaxId { get; set; }
public Guid VendorTypeKey { get; set; }
public Guid? ParentKey { get; set; }
[ForeignKey("Id")]
public virtual Address Address { get; set; }
}
Try this:
[Table("EE.Address")]
public partial class Address {
[Key]
public Guid Id { get; set; }
[StringLength(50)]
public string Address1 { get; set; }
[StringLength(50)]
public string Address2 { get; set; }
[StringLength(50)]
public string City { get; set; }
[StringLength(5)]
public string State { get; set; }
[StringLength(30)]
public string PostalCode { get; set; }
[StringLength(10)]
public string CountryCode { get; set; }
[ForeignKey("Vendor")]
public Guid EntityKey { get; set; }
public virtual Vendor Vendor { get; set; }
// EntityKey should be Vendor.Id
}
[Table("EE.Vendor")]
public partial class Vendor {
[Key]
public Guid Id { get; set; }
[StringLength(50)]
public string Name { get; set; }
[StringLength(50)]
public string AlternativeName { get; set; }
[StringLength(50)]
public string VendorCode { get; set; }
[StringLength(50)]
public string TaxId { get; set; }
public Guid VendorTypeKey { get; set; }
public Guid? ParentKey { get; set; }
[ForeignKey("Address")]
public Guid AddressId {get; set; }
public virtual Address Address { get; set; }
}

Resources