asp.net mvc adding custom column to identity role table - asp.net-core-mvc

This is how I add new column to Identity role table
public class ApplicationRole : IdentityRole
{
public ApplicationRole() : base() { }
public ApplicationRole(string name, long customId) : base(name)
{
this.CustomId= customId;
}
public virtual long CustomId{ get; set; }
}
In dbContext , I added
modelBuilder.Entity<ApplicationRole>().ToTable("AspNetRoles");
using this , new column CustomId is added successfully to AspNetRoles table using migration .
But when I have to call role table like
private readonly IdentityDbContext db_Identity;
..
..
db_Identity.Roles.Select(x=>x.CustomId)
I can't find newly added column CustomId here .
Is there any step I missed ?
Update
With #Chirs's answer , I can get CoustomId , but when I run , I got this error
Cannot create a DbSet for 'IdentityRole' because this type is not included in the model for the context

If you are using custom Identity models, you also need to inherit from one of the generic IdentityDbContext classes and specify your custom type in the appropriate type param. In this case, you just need something like:
public class MyDbContext : IdentityDbContext<ApplicationUser, ApplicationRole, string>
Then use your custom context class:
private readonly MyDbContext db_Identity;

Related

EF Core Oracle table does not exist error

I am using Dot Net Core 3.1 , EF Core and Oracle.EntityframeworkCore
Steps I followed :
Created a table named "USER" in Oracle using Toad , with following DDL statement
CREATE TABLE POLICYAPP.USER {
ID NUMBER GENERATED BY DEFAULT AS IDENTITY,
USERNAME VARCHAR2(10) NOT NULL,
PASSWORDHASH VARCHAR2(30) NOT NULL
PRIMARY KEY(ID)
};
where the schema name is "POLICYAPP"
Verified that the table "USER" is present in the schema "POLICYAPP"
Created Dot net Core WebAPI project in Visual Studio 2019
Created "Models" folder and created class "User.cs" with below definition
[Table("USER", Schema = "POLICYAPP")]
public class User
{
[key]
[column("ID")]
public int id {get; set;}
[column("USERNAME")]
public string username {get; set;}
[column("PASSWORDHASH")]
public string passwordhash {get; set;)
}
Create AppDbContext class that contains following
public DbSet Users {get; set;}
Created "Repositories" folder and created interface "IAuthRepository" with method findByUsername
Also, created class "AuthRepository" that implements the interface "IAuthRepository" using LINQ query
Modified Startup.cs to include following in ConfigureServices method
var connstring = Configuration.GetConnectionString("poldb");
services.AddDbContext<AppDbContext> {
options => options.useOracle(connstring)
};
services.AddScoped<IAuthRepoistory, AuthRepository>;
The file appsettings.json has proper connection string.
Created "Controllers" folder and created class "AuthController" in the folder
The controller invokes the repository find method to search by username
The issue is :
When I run the app and enter url http:\localhost:10220\api\Authn\John, it fails with error
"OracleException: ora-00942 table or view does not exist"
Added below code in AppDbContext.cs , still get the same error
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.HasDefaultSchema("POLICYAPP");
}

Retrieve custom profile data from IdentityUser list with linq

ASP.Net Core 3 MVC web application with Identity
My DB context is
public class ApplicationDbContext : IdentityDbContext
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{}
etc...
So Users, from IdentityUserContext is a public virtual DbSet, and is instantiated as
DbSet<Microsoft.AspNetCore.Identity.IdentityUser> Users
However, I have defined ApplicationUser : IdentityUser to define my own profile data.
public class ApplicationUser : IdentityUser
{
[Display(Name = "Is Manager")]
public bool IsSupervisor { get; set; }
etc....
So, I have configured services in startup.cs as:
services.AddDefaultIdentity<ApplicationUser>(options => options.SignIn.RequireConfirmedAccount = true)
I have set up my UserManager as
private readonly UserManager<ApplicationUser> _userManager
But when I try to use LINQ to access and filter User records based on my custom profile information (in the record 'Detail' call to the controler), I'm told that those custom attributes are not available:
var managers = new List<SelectListItem>();
managers.AddRange(_context.Users.Where(x => x.IsSupervisor == true).Select(manager => new SelectListItem
{
Text = manager.DisplayName,
Value = manager.Id.ToString()
}).ToList());
ViewBag.ManagersList = managers;
/Users/robert/Projects/mvc/Vacate/Controllers/EmployeesController.cs(59,59): Error CS1061: 'IdentityUser' does not contain a definition for 'IsSupervisor' and no accessible extension method 'IsSupervisor' accepting a first argument of type 'IdentityUser' could be found (are you missing a using directive or an assembly reference?) (CS1061) (Vacate)
So, without using a separate table to store profile information, is there a way to use LINQ against Users accessing your custom profile members? Sort of 'cast' Users to be the correct ApplicationUser type in the LINQ call? Or did I miss something when setting up the ApplicationUser class for use in Identity?
You should make your default ApplicationDbContext use the new ApplicationUser :
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
}
The update your database : Add-migration , Update-Database .

How to change the primary key for a EntityData derived class default string Id property to an int property?

I recently started to learn about Azure Mobile Services, I followed this tutorial about it and the classes for my model are required to inherit from the EntityData class.
From the EntityData source code, an Id property is already defined to act as a primary key, but it is defined as string which doesn't work for my Model that uses int.
My class looks like this:
public partial class Role : EntityData
{
public Role()
{
this.Users = new HashSet<User>();
}
[Key]
public int RoleId { get; set; }
public string Title { get; set; }
public virtual ICollection<User> Users { get; set; }
}
If I try to use this class, I get an error message saying an Id property is already defined.
Is there a way to define a different property as a primary key? In case this change is not possible, is there a way to use this string Id property as an incremental primary key?
The best solution is to use automapper. Here's a blog post that outlines how to do it, essentially you store an int, but transform it into a string when it is sent over the wire:
http://blogs.msdn.com/b/azuremobile/archive/2014/05/22/tables-with-integer-keys-and-the-net-backend.aspx

Convert IQueryable<T> to IQueryable<Y>

I'm try to do this : I'm using EF code first to map an old existing database. There's many fields with the wrong type (ex: char(1) used as boolean) so I've created a wrapper class for my db context that maps perfectly to the database table. Now, I want to expose an IQueryable of my Entity type on my repository. See my example :
public class MyContext:DbContext
{
public DbSet<WrappedEntity> WrapperEntities;
}
public class Repository
{
private MyContext _context;
//contructors omitted
public IQueryable<Entity> GetEntities()
{
return _context.WrapperEntities; //doesn't compile, I need some convertion here
}
}
I already have my convertion routine, the only thing missing is a way to query my DbContext thought my repository without exposing the WrappedEntity class, Is it possible and how ?
Thanks.
Usually you project with Queryable.Select to change the type of your query...
public IQueryable<Entity> GetEntities()
{
return _context.WrapperEntities.Select(x => new Entity(){...});
}

Trying to use Entity Framework with asp.net MVC3

I'm trying to make EntityFramework work with ASP .NET MVC3 using this tutorial:
http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/creating-an-entity-framework-data-model-for-an-asp-net-mvc-application
Ok, I have my database, my .edmx model, model classes but one first thing I don't get is:
How does my DbContext derived class even know my .emdx model ? I don't fine where the "link" is created in this tutorial (maybe having several thing with the same name "SchoolContext", for the context as for the connexionstring is confusing ...)
When I run what I got for now with the code:
MMContext context = new MMContext();
List<EntityUser> testList = (from u in context.Users
select u).ToList();
I get:
System.Data.Edm.EdmEntityType: : EntityType 'EntityUser' has no key defined. Define the key for this EntityType.
System.Data.Edm.EdmEntitySet: EntityType: EntitySet �Users� is based on type �EntityUser� that has no keys defined.
Thank you for your help.
Assuming you are using the Code-First approach, you have to define a Key in your Users class:
public class User
{
public int Id { get; set; }
// ...
}
As mentioned from Kyle, if your ID field is not named "Id" you have to add the [Key] attribute:
using System.ComponentModel.DataAnnotations;
public class User
{
[Key]
public int u_Id { get; set; }
// ...
}

Resources