How to access users when Identity project uses EF Core and Class Library uses EF6 with same database - asp.net

We have a .NET Core project that uses Identity 3 and IdentityDbContext using EF Core for user management. The generated tables are stored in a common SQL server database that is also being used by another project in our solution that is a .NET 4.5.2 Framework DataLayer using EF6.
(Just some more background - the .NET Core project is an authorization server that uses OpenIddict to implement OpenIdConnect and Oauth2 and is configured with Identity so that we can save users to the database and login and authenticate)
Once we've authenticated, we make calls to our API end point. The API talks to a DataLayer that works with EF6. From this project I need to fetch the logged in user and work with users for various queries. Ideally, I wanted to use and extend the same AspNetUsers table.
I am wondering what the recommended approach is here? If I try to generate a User DbContext in the EF6 project I have to add a new migration and the scaffolding wants to create a new table - one that already exists in the database. I am a little unsure about having 2 separate contexts in 2 different projects and how these can "play nice" together.

I have handled similar scenario recently. I followed this approach.
I have a separate Class Library for Data Layer, which has Identity related Repositories/Stores, migrations and DbContext. The DbContext takes connection string from the host project.
.Net Core project has connection string specified in appSettings.json. This connection string points to same database. This project implements IdentityServer3 and acts as Token Service.
.Net 4.5.2 project has connection string specified in web.config . This also points to same database. This app gets token from .net core project and uses that Bearer Token to access other APIs.
I created another project to keep the Entities and this project is referenced in both .net core and .net hosts.
This way i have one common data layer for 2 host projects and 2 different service/business layers for 2 host projects. It is working nicely for me.
As EF 7.0 doesn't support seeding, I have a console app for seeding data into database. Even this console app accesses the same database through Data Layer.
So 3 different projects are accessing same database.
I can't share my code with public. I hope this helps.

I was able to get this to work. The main issue is that I just wanted to access my AspNetUsers table that was generated by Identity 3 in the DotNet Core project in my DotNet 4.51 DataLayer class library project.
I achieved this by creating a User.cs Entity class in the class library EF 6 project and making sure it's properties matched the columns from the Identity 3 generated ApplicationUser.cs class.
User.cs
public class User{
[Key]
public string Id { get; set; }
public int AccessFailedCount { get; set; }
public string ConcurrencyStamp { get; set; }
public string Email { get; set; }
public bool EmailConfirmed { get; set; }
public bool LockoutEnabled { get; set; }
public DateTimeOffset? LockoutEnd { get; set; }
public string NormalizedEmail { get; set; }
public string NormalizedUserName { get; set; }
public virtual string PasswordHash { get; set; }
public string PhoneNumber { get; set; }
public bool PhoneNumberConfirmed { get; set; }
public virtual string SecurityStamp { get; set; }
public bool TwoFactorEnabled { get; set; }
public string UserName { get; set; }
}
I then set up an EntityConfiguration to map to the AspNetUsers table
UserConfiguration.cs
public class UserConfiguration : EntityTypeConfiguration<User>
{
public UserConfiguration()
{
ToTable("AspNetUsers");
}
}
In my DbContext class I added a DbSet for my Users entity:
public virtual IDbSet<User> Users { get; set; }
I then ran the Add-Migration command to scaffold the changes. Once generated, I commented out the code and applied the migration to the database. This generates a row in the __MigrationsHistory table for the AspNetUsers table but doesn't try to recreate the table.
I was then able to successfully talk to the AspNetUsers table from the DataLayer EF6 project :)
Also it seems that I can also extend the AspNetUsers table with custom columns now by adding properties to my User.cs class and doing the migrations in the EF6 Datalayer project.

Related

ASP.NET tables and identity tables containing duplicate data

I am using .NET Framework 4.6.1 and Entity Framework 6.0.0.0.
I am working on an ASP.NET web application (Web API). When I see my database created by Entity Framework, the tables shown below like ASP.NET User & Application Users which have some duplicate data. Also, in IdentityUserRoles and ASPNETUserRoles also having duplicate data.
I don't want to keep these duplicate tables mainly want to continue with ASP.NET tables not identity tables. How can I achieve this, and what do I need to do? Why did these duplicate tables with the same data get created?
Below is User Model I am using :-
public class User
{
[Key]
public int id { get; set; }
public string application_user_id { get; set; }
[ForeignKey("application_user_id")]
public virtual ApplicationUser applicationuser { get; set; }
public DateTime? start_date { get; set; }
public DateTime? end_date { get; set; }
public virtual ICollection<Test> Tests{ get; set; }
}
I think the answer to your question is to inherete the properties of the identity table in your tables.
To make it clear you just need to change your model into something like this:
public class user : IdentityUser
{
...
}
this way the columns in identity user will be added to the user table, in addition to your personnalized columns of the user table, I'm not sure if I made my answer clear enough but I will put here a link if you want to learn more about how to personnalize the identity tables : Custom Identity model

How to update / generate database table model?

I'm learning ASP.NET Core and I'm having some problems with the following scenario:
I created an extension class for IdentityUser provided by Microsoft.AspNetCore.Identity, the extension class add some extra field to the default database AspNetUsers:
public class ApplicationUser : IdentityUser
{
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime BirthDate { get; set; }
public string LockoutMessage { get; set; }
public string SessionId { get; set; }
}
I was able to update the table structure executing the following commands:
add-migration <migration name> -context <app context>
update-database
Problem
Suppose now I used the software Microsoft SQL Server Management Studio for create another table called UserDetails which have as FK the id of the AspNetUsers table.
I want generate the class inside the Models folder with all the properties from my application, so I don't need to write manually the property of the table of the new table, how can I do that?
I tried: update-database but not seems to work.
The only way to bring in stuff from a database is with Scaffold-DbContext. However, that's an all or nothing affair. It's going to create entity classes for every table in the database (regardless of whether they already exist) and a DbContext to boot.
Either you're using code first and you create your entities and generate migrations that you run against the database OR you make changes to the database and then use the Scaffold-DbContext command to generate the context and all the associated entities. You cannot mix and match.
Long and short, you need to pick a strategy and stick with it. If you're more comfortable with the database then do everything there and scaffold the code from that. Otherwise, if you want to use code first, then make a commitment to that and never manually touch your database.

I could not connect to database instance created with Entity Framework generated from model

I created a web application and a model. Then I generated a dbcontext class and a database instance. After I built the project, I tried to connect to that database from Server Explorer in Visual Studio, but could not connect.
I tried to test connection but got an error:
This connection cannot be tested because the specified database does not exist or is not visible to the specified user
Whenever I tried to scaffold view or controller I got this error:
Unable to retrieve metadata for ... one or more validation errors were detected during model generation
ModelsTable is based on type TestModel that has no keys defined.
When I created database object in controller class and write query got same error no key defined.
Also made updates on packages and tried again. I think my connection string is correct.
Here is my model.
public class TestModel
{
[Key]
public string ID { get; } = Guid.NewGuid().ToString();
public string AreaName { get; set; }
public bool IsWorking { get; set; }
public string UserName { get; set; }
public DateTimeOffset Time { get; set; }
}
So I could not use scaffolding, Entity Framework and write query.
Here is my dbcontext class.
public class ModelDB : DbContext
{
public ModelDB()
: base("name=ModelDB")
{
}
public DbSet<TestModel> ModelsTable { get; set; }
}
I searched on internet tried founded solutions but did not understand and could not solve. I hope did not ask unnecessary questions. Thanks for your helping.
Are you using Code First? If so I think you need to generate migrations.
In visual studio go to Package Manager Console and run this commands:
Add-Migration "modelClassName"
Update-Database –Verbose
For more information refer to this link: https://msdn.microsoft.com/en-us/library/jj591621(v=vs.113).aspx
You are missing the set; in the field ID.

Create DB context in different project

There is option to create DB which the DB context not allocated in the same MVC project,
i.e create one MVC in project A and the DB context in In project B which can use the model of model A
The reason is that I want to access to the DB from different project without any dependence
Edit.
I've created this in project A and generate the view and controller by scaffold and its working,now what should I do in project B to access to this DB context?
namespace DiffDBContext2.Models
{
public class Ad
{
public string Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class AdModelDbContext : DbContext
{
public DbSet<ad> Ad { get; set; }
}
}
I am not sure what do you exactly want. But what I feel is that you want to have data access later as a separate project than your client (mvc). In this case you can have you dbcontext in another project but you need to have connection string in both mvc and data access project. when executing it always request connection string from client.

How to Add Extra Fields of FistName and LastName in Userprofile of Asp.Net MVC 4 Simple Membership?

I want to add 2 Extra fields in UserProfile Asp.Net Simple membership, But unable to add and not find any help from internet. Please give me some solutions.
Thanks in advance
To add fields to UserProfile in SimpleMembership (I will assume you want to use migrations and EF):
Ensure you have enabled migrations (use the Enable-Migration in the package manager console)
Edit the UserProfile class (assuming you are using, for example, the Visual Studio 2012 -> New Project -> ASP.NET MVC 4 Web Application -> Internet Application template, this will be created for you) to add your new properties (example below)
Add a migration which will update your database using the Add-Migration command.
Optionally edit the generated migration to handle default values and non-nullable fields.
Run that migration against your development database using the Update-Database command.
I have provided an overview about how SimpleMembership works, with UserProfile in this answer. Note that UserProfile can be moved from the UsersContext to the same DbContext as all your other classes, it does not have to be in a separate context.
SimpleMembership is designed to play well with code-first EF development, so that is the process I have outlined above. An example updated UserProfile class with a Forename, Surname and a LoginCount field would look like:
[Table("UserProfile")]
public class UserProfile
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string UserName { get; set; }
[MaxLength(40)]
[Required]
public string Forename { get; set; }
[MaxLength(40)]
[Required]
public string Surname { get; set; }
[Required]
public int LoginCount { get; set; }
}
References:
ASP.NET MVC 4 Entity Framework Scaffolding and Migrations - task 3 shows how to enable migrations
MSDN: Code First Migrations - everything you need to know about migrations
StackOverflow: How do I use my own database with SimpleMembership and WebSecurity? What is MVC4 security all about?

Resources