I am currently trying to build a new application using EF6 Code First, I manage to create the database based on my models no problem.
Now what I want to do is use asp.net membership features. So I will have to have the database schema inside my database.
How can I do this?
There is information around the internet on using the simplemembershipprovider with EF, but it is very confusing.
Just so you have an idea of what I have done so far...(below)
So what is the best way to use membership with EF?
namespace AsoRock.Data.DTOs
{
public class Customer
{
[Key]
public int CustomerId { get; set; }
public string Title { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public string HomeNumber { get; set; }
public string MobileNumber { get; set; }
public string Gender { get; set; }
public DateTime Dob { get; set; }
}
public class Order
{
[Key]
public int OrderId { get; set; }
public Address Address { get; set; }
public Customer Customer { get; set; }
public List<Product> Products { get; set; }
}
public class Product
{
[Key]
public int ProductId { get; set; }
public string ProductName { get; set; }
public decimal ProductPrice { get; set; }
}
public class Address
{
[Key]
public int AddressId { get; set; }
public Customer Customer { get; set; }
public string AddressLine1 { get; set; }
public string AddressLine2 { get; set; }
public string City { get; set; }
public string PostCode { get; set; }
public string LastUsed { get; set; }
public bool isDefault { get; set; }
}
public class AsoRockContext : DbContext
{
public DbSet<Customer> Customers { get; set; }
public DbSet<Address> Addresses { get; set; }
public DbSet<Order> Orders { get; set; }
// public DbSet<Product> Products { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Order>().HasMany(p => p.Products).WithMany().Map(m =>
{
m.MapLeftKey("OrderId").MapRightKey("ProductId").ToTable("OrderdProducts");
});
base.OnModelCreating(modelBuilder);
}
}
}
If you are using MVC 5 then you can change your
public class AsoRockContext : DbContext
to be
public class AsoRockContext : IdentityDbContext<ApplicationUser>
Then create your ApplicationUser
public class ApplicationUser : IdentityUser
{ //You can add extra properties in if you want
public string FirstName { get; set; }
public string LastName { get; set; }
//Or add a link to your customer table
public Customer CustomerDetails { get; set; }
}
Asp.net MVC 4+ comes with asp.net membership provider.
So you context name is TestConnection then
in the AccountModel in Model Directory, Change the defaultConnection to TestConnection
like this, then it will create membership table in your DB.
public UsersContext()
: base("TestConnection")
{
}
to know more about how it is achieve see the code, see the AccountController file and find the following in top
[InitializeSimpleMembership]
public class AccountController : Controller
Inspect the [InitializeSimpleMembership] attribute to learn how it is implemented.
Related
I am working on Asp.net core 5 Web-api, I am using many to many relationship between User entity and Permission entity, and I need to load users permission from the database using eager loading but the data is returning a looped information including users full information but I only load the permissions. I am using a Dto to return the Json data. Here is my models and my code
Permission Model
public class Permission
{
public int Id { get; set; }
public string ClaimName { get; set; }
public IList<UserPermission> UserPermissions { get; set; }
}
UserPermission model
public class UserPermission
{
public int UserId { get; set; }
public AppUser AppUser { get; set; }
public int PermissionId { get; set; }
public Permission Permission { get; set; }
}
User model
public class AppUser
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public ICollection<Photo> Photos { get; set; }
public DateTime Created { get; set; } = DateTime.Now;
public DateTime LastActive { get; set; }
public IList<UserPermission> UserPermissions { get; set; }
public bool Status { get; set; }
}
My user Dto
public class UserDto
{
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public ICollection<Photo> Photos { get; set; }
public ICollection<UserPermission> UserPermissions { get; set; }
public string Token { get; set; }
}
My function
var sss = _context.UserPermissions
.Include(l => l.Permission)
.Where(v => v.UserId == user.Id)
.ToList();
Use [JsonIgnore] on the properties that we want to exclude.
note that we should use "using Newtonsoft.Json" name space not using "System.Text.Json.Serialization"
I have three related Entities in my blazor application Opportunity, AppUser and AssignedOpportunity, What I want to achieve is to map Opportunity and AppUser to a DTO Object ReturnAssignedOpportunityDTO which has similar fields as the entities, using AutoMapper, but am not sure how to do that, below are the entities
public partial class AssignedOpportunity
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
[ForeignKey("OpportunityID")]
public string OpportunityID { get; set; }
public string Status { get; set; }
public Opportunity opportunity { get; set; }
[ForeignKey("UserID")]
public string UserID { get; set; }
public AppUser User { get; set; }
}
The opportunity
public partial class Opportunity
{
public Opportunity()
{
AssignedOpportunities= new HashSet<AssignedOpportunity>();
}
[Key]
public string ID { get; set; }
public string OpportunityName { get; set; }
public string Description { get; set; }
public string CreatedBy { get; set; }
public DateTime DateCreated { get; set; }
public double EstimatedValue { get; set; }
public string EmployeeNeed { get; set; }
public double RealValue { get; set; }
public string Location { get; set; }
public string ReasonStatus { get; set; }
public string Status { get; set; }
public virtual ICollection<AssignedOpportunity> AssignedOpportunities { get; set; }
}
AppUser Class
public partial class AppUser : IdentityUser
{
public AppUser()
{
AssignedOpportunities = new HashSet<AssignedOpportunity>();
}
public string FirstName { get; set; }
public string MiddleName { get; set; }
public string LastName { get; set; }
public string Gender { get; set; }
public string Street { get; set; }
public string City { get; set; }
public string LGA { get; set; }
public string State { get; set; }
public virtual ICollection<AssignedOpportunity> AssignedOpportunities { get; set; }
}
Here's the DTO Object I want to map to.
public class ReturnOpportunitiesDTO
{
public int ID { get; set; }
public string OpportunityID { get; set; }
public string OpportunityName { get; set; }
public double EstimatedValue { get; set; }
public string EmployeeNeed { get; set; }
public double RealValue { get; set; }
public string Location { get; set; }
public string UserID { get; set; }
public string UserFullName { get; set; }
public string Status { get; set; }
}
Here is my query to fetch the records
var result = await _context.AssignedOpportunities.Include(o => o.opportunity).
ThenInclude(a => a.User).
Where(a=>a.UserID==UserID.ToString()).ToListAsync();
return result;
This is how i usually setup Map Profile
public AssignArtisanProfile()
{
CreateMap<AssignedOpportunity, ReturnOpportunities>();
}
But since I want to map multiple entities, how do I include the other entity
Your scenario is just another example of flattening a complex object. You have properties in child objects, which you want to bring to the ground level, while still leveraging AutoMapper mapping capabilities. If only you could reuse other maps from app user and opportunity when mapping from assigned opportunity to the DTO... Well, there is a method called IncludeMembers() (see the docs) that exists precisely for such case. It allows you to reuse the configuration in the existing maps for the child types:
config.CreateMap<AssignedOpportunity, ReturnOpportunitiesDTO>()
.IncludeMembers(source => source.opportunity, source => source.User);
config.CreateMap<Opportunity, ReturnOpportunitiesDTO>();
config.CreateMap<AppUser, ReturnOpportunitiesDTO>()
.ForMember(
dest => dest.UserFullName,
options => options.MapFrom(source =>
string.Join(
" ",
source.FirstName,
source.MiddleName,
source.LastName)));
Usage:
var mappedDtos = mapper.Map<List<ReturnOpportunitiesDTO>>(assignedOpportuniesFromDatabase);
These are my models:
public class Company
{
public int CompanyId { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public string Email { get; set; }
public string Url { get; set; }
//...
}
public class HeadOffice : Company
{
public int HeadOfficeId { get; set; }
public virtual List<BranchOffice> BranchOffice { get; set; } = new List<BranchOffice>();
}
public class BranchOffice : Company
{
public int BranchOfficeId { get; set; }
public virtual HeadOffice HeadOffice { get; set; }
}
I wanted the following database structure:
Table Company
CompanyId (PK)
Name
Address
Email
Url
Table HeadOffice
HeadOfficeId (PK)
CompanyId (FK)
Table BranchOffice
BranchOfficeId (PK)
HeadOfficeId (FK)
CompanyId (FK)
How can I do this?
When I create this migration, the EF creates just one table, with all columns! I don't want this approach!
You would have to change your Model to look like this, note that you can't use inheritance using this approach:
public class Company
{
public int CompanyId { get; set; }
//...
}
public class Company
{
public int CompanyId { get; set; }
public string Name { get; set; }
//...
}
public class HeadOffice
{
[ForeignKey(nameof(Company))]
public int CompanyId { get; set; }
public Company Company { get; set; }
// Add Properties here
}
public class BranchOffice
{
[ForeignKey(nameof(Company))]
public int CompanyId { get; set; }
public Company Company { get; set; }
// Add Properties here
}
Your DbContext:
public class YourContext : DbContext
{
public DbSet<Company> Companys { get; set; }
public DbSet<HeadOffice> HeadOffices { get; set; }
public DbSet<BranchOffice> BranchOffices { get; set; }
public YourContext(DbContextOptions<YourContext> options)
: base(options)
{
}
}
You could then use EF Core Migrations. The command would look somewhat like this:
dotnet ef migrations add Initial_TPT_Migration -p ./../../ModelProject.csproj -s ./../../ModelProject.csproj -c YourContext -o ./TptModel/CodeFirst/Migrations
It generats a Class Initial_TPT_Migration that contains methods to generate your database.
Usage
To query you would need to map Company Properties to the fieldnames. If you combine this with the Repository Pattern (link), it could actually be as convenient as the default approach in EF Core currently is to use.
YourContext ctx = ...
// Fetch all BranchOffices
var branchOffices = ctx.BranchOffices
.Select(c => new BranchOffice()
{
CompanyId = c.CompanyId,
Name = c.Company.Name,
})
.ToList();
You can find more informations about this approach here.
You can find an answer here https://learn.microsoft.com/en-us/aspnet/core/data/ef-mvc/inheritance?view=aspnetcore-2.1
Also check this topic out if you need many inherited classes against one table
https://learn.microsoft.com/en-us/ef/core/modeling/relational/inheritance
Copying the code here just in case microsoft used to mess with urls and docs
Each inherited type per table
public class SchoolContext : DbContext
{
public SchoolContext(DbContextOptions<SchoolContext> options) : base(options)
{
}
public DbSet<Student> Students { get; set; }
public DbSet<Instructor> Instructors { get; set; }
public DbSet<Person> People { get; set; }
protected override void OnModelCreating(ModelBuilder b)
{
b.Entity<Student>().ToTable("Student");
b.Entity<Instructor>().ToTable("Instructor");
b.Entity<Person>().ToTable("Person");
}
}
public abstract class Person
{
public int ID { get; set; }
public string LastName { get; set; }
public string FirstMidName { get; set; }
}
public class Instructor : Person
{
public DateTime HireDate { get; set; }
}
public class Student : Person
{
public DateTime EnrollmentDate { get; set; }
}
Many inherited types in one table
public class MyContext : DbContext
{
public DbSet<Blog> Blogs { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.HasDiscriminator<string>("blog_type")
.HasValue<Blog>("blog_base")
.HasValue<RssBlog>("blog_rss");
}
}
public class Blog
{
public int BlogId { get; set; }
public string Url { get; set; }
}
public class RssBlog : Blog
{
public string RssUrl { get; set; }
}
I have an ASP.NET MVC project supporting multiple languages.
the tables (User,Gender,GenderTranslate) had nested inheritance
User inherit from Gender and Gender inherit from GenderTranslate
I have these tables
User table :
public partial class User
{
public int Id { get; set; }
public string Name { get; set; }
public Nullable<int> GenderID { get; set; }
public virtual Gender Gender { get; set; }
}
and Gender table:
public partial class Gender
{
public Gender()
{
this.GenderTranslates = new HashSet<GenderTranslate>();
this.Users = new HashSet<User>();
}
public int Id { get; set; }
public string Icon { get; set; }
public string Value { get; set; }
public virtual ICollection<GenderTranslate> GenderTranslates { get; set; }
public virtual ICollection<User> Users { get; set; }
}
and Language table:
public partial class Lang
{
public Lang()
{
this.GenderTranslates = new HashSet<GenderTranslate>();
}
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<GenderTranslate> GenderTranslates { get; set; }
}
and GenderTranslate table :
public partial class GenderTranslate
{
public int LangID { get; set; }
public int GenderID { get; set; }
public string Desc { get; set; }
public virtual Gender Gender { get; set; }
public virtual Lang Lang { get; set; }
}
When I get users I need to get GenderTranslate.Desc, not Gender.Value.
How can I do that using Entity Framework? Please help me
I have few Domain Models - Address, Customer, Employee, StoreLocation. Address has many to one relationship with Customerand Employee and one to one relationship with StoreLocation.
public class Address
{
public int Id;
public string Line1 { get; set; }
public string Line2 { get; set; }
public string Line3 { get; set; }
}
public class Customer
{
public int Id { get; set; }
public string Name { get; set; }
public IList<Address> Addresses { get; set; }
}
public class StoreLocation
{
public int Id { get; set; }
public string ShortCode { get; set; }
public string Description { get; set; }
public Address Address { get; set; }
}
public class Employee
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime Dob { get; set; }
public IList<Address> Addresses { get; set; }
}
How to Map this relationship?. I am using ASP.NET MVC 3.0 and Entity Framework 4.1.
If you are using code-first (I think you want this, else, you have to edit your Q), the first way is the way explained below:
Entities:
public class Address {
[Key]
public int Id { get; set; }
public string Line1 { get; set; }
public string Line2 { get; set; }
public string Line3 { get; set; }
public virtual Customer Customer { get; set; }
public virtual StoreLocation StoreLocation { get; set; }
public virtual Employee Employee { get; set; }
public int? CustomerId { get; set; }
public int? EmployeeId { get; set; }
}
public class Customer {
[Key]
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<Address> Addresses { get; set; }
}
public class StoreLocation {
[Key]
public int Id { get; set; }
public string ShortCode { get; set; }
public string Description { get; set; }
public virtual Address Address { get; set; }
}
public class Employee {
[Key]
public int Id { get; set; }
public string Name { get; set; }
public DateTime Dob { get; set; }
public virtual ICollection<Address> Addresses { get; set; }
}
DbContext inherited class:
public class ManyOneToManyContext : DbContext {
static ManyOneToManyContext() {
Database.SetInitializer<ManyOneToManyContext>(new ManyOneToManyInitializer());
}
public DbSet<Address> Addresses { get; set; }
public DbSet<Customer> Customers { get; set; }
public DbSet<StoreLocation> StoreLocations { get; set; }
public DbSet<Employee> Employees { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
modelBuilder.Conventions.Remove<IncludeMetadataConvention>();
modelBuilder.Entity<Customer>().HasMany(c => c.Addresses).WithOptional(a => a.Customer).HasForeignKey(a => a.CustomerId);
modelBuilder.Entity<StoreLocation>().HasRequired(s => s.Address).WithOptional(a => a.StoreLocation).Map(t => t.MapKey("AddressId"));
modelBuilder.Entity<Employee>().HasMany(e => e.Addresses).WithOptional(a => a.Employee).HasForeignKey(e => e.EmployeeId);
}
}
Context Initializer:
public class ManyOneToManyInitializer : DropCreateDatabaseAlways<ManyOneToManyContext> {
protected override void Seed(ManyOneToManyContext context) {
}
}
That will create the db-schema below:
Let me know if you have any questions or need clarifications on any part.