Navigation properties between IdentityUser and Custom Tables using Blazor WASM Hosted model - c#

I'm using Entity Framework with Microsoft Identity Client on a Blazor WASM project with a hosted API. Having 2 tables related by Id - Events and EventParticipants I want to build a page that will display Event details with the list of Participants and their basic info (UserName + profilePicture). They look like this:
public class Event
{
public Guid Id { get; set; }
public string Name { get; set; }
public string Country { get; set; }
public string City { get; set; }
public DateTime? StartDate { get; set; }
public DateTime? EndDate { get; set; }
public ICollection<EventParticipant> Participants { get; set; }
}
public class EventParticipant
{
public int Id { get; set; }
public string? Status { get; set; }
public int? Place { get; set; }
[ForeignKey(nameof(Event))]
public Guid EventId { get; set; }
public Event Event { get; set; }
public string UserId { get; set; }
//no clue how to implement user model here
}
Above classes are stored on Shared project while ApplicationUser : IdentityUser is on the Server. Because of that I have no idea how to link EventParticipant with User table (AspNetUsers). Any ideas?

Related

How to design one to many relationship in efcore?

Hi I am working on entity framework core. I have user table and user may be part of multiple projects. And user for each project has to enter time sheet data. For example below is my user table.
public class User
{
[Key]
public string Id { get; set; }
public string name { get; set; }
public string emailId { get; set; }
}
Below is my project table.
public class Project
{
[Key]
public string Id { get; set; }
public string Name { get; set; }
public string userId { get; set; }
}
Here User may belong to multiple projects. Now for each project user has to enter timesheet data. Below is timesheet table.
public class TimeSheetData
{
[Key]
public string id { get; set; }
public string project_id { get; set; }
public string hours_logged { get; set; }
}
I have to define this in entity framework core. One user may be part of multiple projects and user needs to enter data to timesheet for each project. How can I define relationship with respect to above table?
In user table Do I need to add something like Public List<Project> Projects? Also In Project table Public List<Timesheet> Timesheets something I have to define here. Can some one help me to understand this? Any help would be greatly appreciated. Thanks
Assuming you will be changing string to int ids, does something below work?
public class User
{
public User()
{
this.Projects = new HashSet<Project>();
}
[Key]
public int Id { get; set; }
public string name { get; set; }
public string emailId { get; set; }
public virtual ICollection<Project> Projects { get; set;}
}
public class Project
{
public Project()
{
this.TimeSheetData = new HashSet<TimeSheetData>();
}
[Key]
public int Id { get; set; }
public string Name { get; set; }
public int userId { get; set; }
[ForeignKey("userId")]
public virtual User User {get; set; }
public virtual ICollection<TimeSheetData> TimeSheetData { get; set;}
}
public class TimeSheetData
{
[Key]
public int id { get; set; }
public int project_id { get; set; }
[ForeignKey("project_id")]
public virtual Project Project {get; set; }
public string hours_logged { get; set; }
}

How add identity and user management into aspnetcore web api?

I'm building asp.net core web api with 3 types of users: Admin, Clients and Programmers. Each of those roles have their own list of tickets. These are entity classes I've already added:
public class User
{
[Key]
public Guid Id { get; set; }
[Required]
[MaxLength(50)]
public string FirstName { get; set; }
[Required]
[MaxLength(50)]
public string LastName { get; set; }
[Required]
public string Address { get; set; }
[Required]
public string Zip { get; set; }
[Required]
[Phone]
public string PhoneNumber { get; set; }
[Required]
[EmailAddress]
public string EmailAddress { get; set; }
[Required]
public Gender Gender { get; set; }
[Required]
[MaxLength(50)]
public string UserName { get; set; }
[Required]
[MaxLength(50)]
public string Password { get; set; }
[Required]
public Role Role { get; set; }
public virtual Programmer Programmer { get; set; }
public virtual Admin Admin { get; set; }
public virtual Client Client { get; set; }
}
public class Client
{
public Guid clientId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public virtual ICollection<Ticket> Tickets { get; set; } = new List<Ticket>();
public Guid Id { get; set; }
public virtual User User { get; set; }
}
public class Admin
{
public Guid adminId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public virtual ICollection<Ticket> Tickets { get; set; } = new List<Ticket>();
public Guid Id { get; set; }
public virtual User User { get; set; }
}
public class Programmer
{
public Guid programmerId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public ProgrammingLanguage ProgrammingLanguage { get; set; }
public Experience Experience { get; set; }
public DetailOriented DetailOriented { get; set; }
public FieldOfInterest FieldOfInterest { get; set; }
public virtual ICollection<Ticket> Tickets { get; set; } = new List<Ticket>();
public Guid Id { get; set; }
public virtual User User { get; set; }
}
I've already created regular DbContext and implemented functionality of my api using that DbContext. Now I want to change users to be IdentityUsers. I'm not sure should I make a new project where UserIdentity will be handled and then pass those users to my api(if so, how can I pass them to api and connect them with their tickets, i.e.do I leave only tickets table in api?) or make users as part of an api as I already did(if so, what would be the best way to change them into identity users so that I can query their tickets later?). Does anyone have any tips/links/similar code samples or something? I would be grateful :)
Out of the box, Identity supports a single set of user profile properties. The easiest solution would be to create an AppUser class that inherits from IdentityUser with ALL of the properties across your user types. Also introduce an interface for each of your user types with the properties they support.
class AppUser: IdentityUser, IAdmin, IProgrammmer, IClient {...}
Based on the IdentityRole associated with the user, you can cast the AppUser instance to the appropriate interface to access the user-specific properties.

EF code Model for e-tender system in MVC4

Am building tender board Application am getting some confusing in how structure my model using >> entity-framework in >> MVC4
Here the descriptions:
In my simple membership Role Table , I have:
(Admin,Tender,Provider,Member)
Administration: he have right to change normal user role from “Member” to “Provider and prove winner bidder after tender organization approved.
Suppliers: Normal users will be assigning as “member” and will be activated by Administration to be provider and then they can bid any projects they want.
Projects: created by Tender Organization Users every project has many requirements
Requirement: each one related to project.
Tenders: Here my problem actually Tender are “Ministries in country and have to be set in system” but each ministry obvious have many users “Manager, let say 5 in each” who will vote for supplier.Mangers can vote to only those suppliers which are laid under the same ministry.
Do I miss others tables?
Also I don’t really know how to structure all the tables with relations and also with (UserprofileTbale, and Role Table):
Here my try, help me on that.
My DBContext:
public class ProjectContext : DbContext
{
public ProjectContext()
: base("OTMSProjects")
{
}
public DbSet<ProjectEntry> Entries { get; set; }
public DbSet<Requiernments> RequiernmentEntries { get; set; }
public DbSet<Supplier> Suppliers { get; set; }
public DbSet<Tender> Tenders { get; set; }
public DbSet<UserProfile> UserProfiles { get; set; }
//public DbSet<UserRoles> UserRoles { get; set; } // do I have to set this too?
}}
My tables:
public class ProjectEntry
{
[Key]
public int ID { get; set; }
[Required]
public string ProjectName { get; set; }
public string Description { get; set; }
public string Statue {get; set; }
public string UplodedFiles { get; set; }
public string Budget { get; set; }
public string EstimateTime { get; set; }
public string Criterias { get; set; }
public DateTime? DueDate { get; set; }
// Relations with others tables
public virtual Tender Tender { get; set; }// every project have only one tender
public virtual ICollection<Supplier> Suppliers { get; set; } // every project have one or more supplier
public virtual ICollection<Requiernments> Requirements { get; set; }
}
........
public class Requiernments
{
[Key]
public int RequiernmentId { get; set; }
public int ID { get; set; }
public string RequiernmentName { get; set; }
public string RequiernmentType { get; set; }
public string RequiernmentPrioritet { get; set; }
public float RequiernmenWhight { get; set; }
public string ProviderAnswer { get; set; }
public string ProviderComments{ get; set; }
public virtual ProjectEntry Projects { get; set; }
}
........
public class Supplier
{
[Key]
public int SupplierId { get; set; }
public int ID { get; set; }
public int SupplierName { get; set; }
public int SupplierCat { get; set; }
public virtual ICollection<ProjectEntry> Projects { get; set; }
}
......
public class Tender
{
[Key]
public int TenderId { get; set; }
public string TenderName { get; set; }
public string TenderMinstry{ get; set; }
public int ID { get; set; }//link to project
public int UserId { get; set; } //this links to the userid in the UserProfiles table
public virtual ICollection<ProjectEntry> Projects { get; set; }
//public virtual ICollection<UserProfile> Userprofile { get; set; }
public virtual UserProfile UserProfile { get; set; }
}
My membership table in my AccountModel created by defualt in Mvc4 ( I only add the RoleTable :
[Table("UserProfile")]
public class UserProfile
{
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string UserName { get; set; }
public string EmailAddress { get; set; }
public ICollection<UserRoles> UserRoles { get; set; }
}
[Table("webpages_Roles")]
public class UserRoles
{
[Key]
public int RoleId { get; set; }
public string RoleName { get; set; }
[ForeignKey("UserId")]
public ICollection<UserProfile> UserProfiles { get; set; }
}
Am not sure also about how to link the Userprofile with Tender Table and supplier Table?
Not sure what you are missed or not. but as per database creation you must follow your business logic and normalization rules.
Some of my suggestions are here:
1. ProjectEntry
here you should create a Status Table separately and gives its reference key as StatusID into the ProjectEntry table.
Requirement
you should create Requirement Priority and Type tables are separately.
Add separate table for provider question and answers. I hope you need to store more than one question answers for single requirement.
Supplier
Add Separate Table for Supplier category
Tender
Create Tender Ministry table separately and give its reference to the tender table.
you should make a table for Uploaded files as Documents. It should contains ID, ProjectId, Documentname, DocumentType, DocumentShortDescription, uplodatedDateTime fields.

How to Disable SignIn/Missing UserManagement Property in ASP.NET MVC 5 EntityFramework

I'm working on a project using Asp.NET MVC 5, but now I'm having some problems since its last update.
Basically, the application user, which inherits from IdentityUser, had an "Management" property, that through it one could block the user, i.e. disable the signin for that user.
How can I do that with the new Entity Framework definitions?
What is the SecurityStamp property of the User?
(Also, in this ASP.NET Tutorial there is an image that shows the project's database, and we can see a "AspNetUserManagement" table that isn't created, but maybe it's just a mistake)
OLD Microsoft.AspNet.Identity.EntityFramework.User:
//...
public string Id { set; get; }
public virtual System.Collections.Generic.ICollection<UserLogin> Logins { set; get; }
public virtual Microsoft.AspNet.Identity.EntityFramework.UserManagement Management { set; get; }
public virtual System.Collections.Generic.ICollection<UserRole> Roles { set; get; }
public string UserName { set; get; }
OLD Microsoft.AspNet.Identity.EntityFramework.UserManagement:
//...
public bool DisableSignIn { set; get; }
public System.DateTime LastSignInTimeUtc { set; get; }
public virtual Microsoft.AspNet.Identity.EntityFramework.User User { set; get; }
public string UserId { set; get; }
NEW Microsoft.AspNet.Identity.EntityFramework.User:
//...
public virtual System.Collections.Generic.ICollection<IdentityUserClaim> Claims { get; }
public virtual string Id { set; get; }
public virtual System.Collections.Generic.ICollection<IdentityUserLogin> Logins { get; }
public virtual string PasswordHash { set; get; }
public virtual System.Collections.Generic.ICollection<IdentityUserRole> Roles { get; }
public virtual string SecurityStamp { set; get; }
public virtual string UserName { set; get; }

How can i expose dto objects using wcf data service with ef code first?

I am trying to make a wcf data service where i dont want to get acces to the database models but instead i want to use Data transfer objects. I have been reading a lot on the internet about how to accomplish this but i cant get a good answer for my problem. It is the first time for me doing something with wcf data services so i am a little inexperienced.
Oke here are my models that are linked to my database using Entity Framework
public class User
{
[Key]
public int UserId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string UserName { get; set; }
public string Email { get; set; }
public string CountryCode { get; set; }
public string PhoneNumber { get; set; }
public ICollection<User> Contacts { get; set; }
public virtual Language Language { get; set; }
public User()
{
Contacts = new List<User>();
}
}
public class Message
{
[Key]
public int MessageId { get; set; }
public DateTime SentDate { get; set; }
public virtual User Sender { get; set; }
public virtual User Receiver { get; set; }
public string Content { get; set; }
public string OriginalCultureInfoEnglishName { get; set; }
public string ForeignCultureInfoEnglishName { get; set; }
}
public class Language
{
[Key]
public int LanguageId { get; set; }
public string CultureInfoEnglishName { get; set; }
}
Now i made a Service.svc which has my DatabaseContext so it can directly acces my database models. What i want to achieve is that instead of directly getting the database models i would like to get the DTO models when i query against my service.
A Example of how my dto's would look like
public class UserDTO
{
public int UserId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string UserName { get; set; }
public string Email { get; set; }
public string Country { get; set; }
public string PhoneNumber { get; set; }
public ICollection<ContactDTO> Contacts { get; set; }
public virtual LanguageDTO Language { get; set; }
public UserModel()
{
Contacts = new List<ContactDTO>();
}
}
public class ContactDTO
{
public int UserId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string UserName { get; set; }
public string Email { get; set; }
public string Country { get; set; }
public string PhoneNumber { get; set; }
public virtual LanguageDTO Language { get; set; }
}
public class LanguageDTO
{
public int LanguageId { get; set; }
public string CultureInfoEnglishName { get; set; }
}
public class MessageDTO
{
public int MessageId { get; set; }
public DateTime SentDate { get; set; }
public virtual ContactDTO Sender { get; set; }
public virtual ContactDTO Receiver { get; set; }
public string Content { get; set; }
public string OriginalCultureInfoEnglishName { get; set; }
public string ForeignCultureInfoEnglishName { get; set; }
}
Now is it possible to do it like this by making a different context that i can use in my service.svc or is there any other way to achieve the this?
for example i would like to get ContactDto by userid which is a user but with less properties because they are not relevant in the client application. I see this happening by a uri http://localhost:54895/Service.svc/ContactDto(1)
Hopefully anyone can clear this up for me because it is really frustrating :)
I'm not sure that what you're interested in is possible, exactly. You are looking to have multiple entity sets per type (aka MEST), and I don't know how well that's supported.
Beyond that point, and into a discussion around DTOs in general...
If you use custom providers, you can implement your own IDataServiceMetadataProvider and IDataServiceQueryProvider. When your service starts, you can make calls into the IDataServiceMetadataProvider to control what entities and properties are exposed or hidden -- including exposing properties that do not actually exist on your entity. The upshot is that you end up with a DTO without coding a DTO class. The exposed metadata is the DTO. This is a good resource for creating your own providers.
In your case, this isn't a 100% solution, because you can't selectively choose when a property is exposed and when it's not.
Hope this helps...

Categories