How to query against dbo.AspNetUserLogins table (IdentityUserLogin entity)? - asp.net-mvc

I am using the standard MVC template with the identity provider in VS 2013.
By extending ApplicationUser:IdentityUser, I am able to access the table AspNetUsers using ApplicationDbContext.
I now want to query the data in another table, AspNetUserLogins. How do I reference it without having to create a new database context and a new Entity Data Model to represent this existing table?

The corresponding entity for dbo.AspNetUserLogins table is IdentityUserLogin class. So we just need to declare an appropriate IDbSet<IdentityUserLogin> or DbSet<IdentityUserLogin> property in the ApplicationDbContext class as follows:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
// ...
public IDbSet<IdentityUserLogin> UserLogins { get; set; }
// ...
}
and then query it as usually:
using (var dbContext = new ApplicationDbContext())
{
var userLogins = dbContext.UserLogins.ToList();
}

I know this is old but for anyone looking to do this with asp .Net Core:
Add user manager to your controller constructor that you can access below by DI.
var user = await _userManager.GetUserAsync(User);
var hello = await _userManager.GetLoginsAsync(user);

Related

how to call stored procedure using ef core and clean architecture

Using asp.net ef core, clean architecture, repository/service & uow pattern
Considering that insert should not be done in repository class and
On the other hand in the service layer we can not call dbContext directly
Suppose we want to use stored procedures or raw queries in some part of the project,
For example, we want to do what is said in the link below
https://www.entityframeworktutorial.net/faq/how-to-set-explicit-value-to-id-property-in-ef-core.aspx
Or call a Stored Precedure that does the insert by Database.ExcecuteSqlCommand
How can we do this without disturbing the architecture?
Where we should call the SP?
My project architecture is so alike this tutorial
Repository Pattern Done Right
Edit:
for more clarification:
this is add method of user repository class:
public class UserRepository : IUserRepository
{
private readonly tablighkadeDbContext _dbContext;
public UserRepository(tablighkadeDbContext dbContext)
{
_dbContext = dbContext;
}
public async Task Add(User user)
{
Entities.User newUser = new Entities.User
{
Email = user.Email,
...
};
await _dbContext.AddAsync(newUser);
}
CompeleteAsync method in unitOfWork class:
public async Task<int> CompeleteAsync()
{
return await _dbContext.SaveChangesAsync();
}
and finally I have service class in core layer, I persist entity like this:
public async Task RegisterUser(UserAddVM userAddVM)
{
var user = await _unitOfWork.Users.GetByEmail(userAddVM.Email);
if (user != null)
{
//...
}
else {
var u = new User
{
Email = userAddVM.Email,
//...
};
await _unitOfWork.Users.Add(u);
await _unitOfWork.CompeleteAsync();
}
}
But I don't know what to do the same using stored procedure,
considering we should not save/update entities in repository class based on this article and some other articles I read
https://programmingwithmosh.com/net/common-mistakes-with-the-repository-pattern/
You can extend generic EFRepository class to have your own implementation. You should expose this implementation via Interface.
Here is an example of OrderRepository: https://github.com/dotnet-architecture/eShopOnWeb/blob/master/src/Infrastructure/Data/OrderRepository.cs
In this example they have implemented GetByIdWithItemsAsync(int id), similarly you can have your own implementation.
You can add a method in UserRepository. If your insert logic is in Stored Proc then you don't require to commit using _dbContext.SaveChanges(). Commit will happen in Stored Proc which will not be in your control. To refresh the state, you can have select for inserted entity at the end of stored proc and which should update the persistent entity .
public async Task Add(User user)
{
var user = _dbContext.Users.SqlQuery("dbo.AddUser #p0 ", user.Name).Single();
}

Constructors and Methods on POCO classes with the IRepository Pattern

Is it okay to have a constructor or other non database accessing methods on POCO classes. For example when passing a view model to a controller.
Controller:
public ActionResult SomeMethod(SomeViewModel model)
{
var entity = new SomePocoClasse(model);
// ... then save entity to database
return SomeActionResult
}
Entity:
public SomeClass() {}
public SomeClass(SomeViewModel model)
{
// create itself based on values in model
}
public void Update(SomeViewModel model)
{
// Update itself base on values in model
}
The first entity constructor is for entity framework or regular creation
var entity = new entity
{
// set up properties
};
The second is for creation from SomeViewModel
var entity = new entity(SomeViewModel);
The method is for updating itself from SomeViewModel
var entity = SomeIRepository.Get(id);
entity.Update(SomeViewModel);
Or is the above bad practice which should go some where else.
Yes and no. In general, it's not necessarily bad practice to have a constructor on a POCO. There's any number of reasons why you might want or need that. However, you need to ensure that you maintain a parameterless constructor as well, or you'll cause issues with things like EF which won't know how to properly initialize your POCO class otherwise.
That said, what you're doing here is not good practice. You haven't provided a ton of code, but it appears that what you're doing is passing in the view model to the POCO constructor to set the properties on the POCO with those values. Rather, what you should be doing is pulling the entity fresh from the database and then mapping over any relevant properties on your view model to that entity instance. I supposed what you're doing could be fine solely when creating a new entity, but that means having two separate ways of populating your POCO class with values depending on whether you're creating or editing. That increases complexity and complexity means higher maintenance costs.
Instead, you should either use a library like AutoMapper or create a utility class to handle the mapping:
public static class SomePocoMapper
{
public static SomePoco Map(SomeViewModel model)
{
return Map(model, null);
}
public static SomePoco Map(SomeViewModel model, SomePoco entity)
{
entity = entity ?? new SomePoco();
// map over property values;
return entity;
}
}
Then in your create action:
var entity = SomePocoMapper.Map(model);
And in your edit action:
var entity = // get entity from database
SomePocoMapper.Map(model, entity);

Seed Database with Users after adding custom fields MVC 5

I've added a couple of custom fields to my ApplicationUser:
public class ApplicationUser : IdentityUser
{
public enum BUserType {IndividualBuyer, IndividualSeller, Broker, Admin};
public string DisplayName;
public BUserType UserType;
I've updated all the views and controllers and I can create new users through my web app. Great.
However, my database seed function doesn't add the new fields to my users. For example, if I create a new user in my initializer, the new fields aren't filled in.
public class ListingInitializer : System.Data.Entity.DropCreateDatabaseAlways<ApplicationDbContext>
{
protected override void Seed(ApplicationDbContext context)
{
var userStore = new UserStore<ApplicationUser>(context);
var userManager = new UserManager<ApplicationUser>(userStore);
if (!(context.Users.Any(u => u.UserName == "arnold#pizzashop.com")))
{
var userToInsert = new ApplicationUser { UserName = "arnold#pizzashop.com", DisplayName = "Arnold Toughguy", UserType = ApplicationUser.BUserType.IndividualSeller };
userManager.Create(userToInsert, "password1234");
}
So my question is, what could be wrong here? I assume userManager.Create does some fancy reflection-to-linq voodoo to find all the fields to persist. Is this not the case? Do I have to add bindings somewhere?
Just a thought, can you just try once after moving the enum definition outside of your POCO class, though I am not absolutely sure that the same will solve your problem.
You can also refer to this video, which may help you somewhat: http://thedatafarm.com/data-access/video-entity-framework-5-enums-and-moving-solution-from-ef-4-3/.

How to use sessions in an ASP.NET MVC 4 application?

I am new to ASP.NET MVC. I have used PHP before and it was easy to create a session and select user records based on the current session variables.
I have looked everywhere on the Internet for a simple step-by-step tutorial that can show me how to create and use sessions in my C# ASP.NET MVC 4 application. I want to create a session with user variables that I can access from anywhere in my controllers and be able to use the variables in my LINQ queries.
Try
//adding data to session
//assuming the method below will return list of Products
var products=Db.GetProducts();
//Store the products to a session
Session["products"]=products;
//To get what you have stored to a session
var products=Session["products"] as List<Product>;
//to clear the session value
Session["products"]=null;
Due to the stateless nature of the web, sessions are also an extremely useful way of persisting objects across requests by serialising them and storing them in a session.
A perfect use case of this could be if you need to access regular information across your application, to save additional database calls on each request, this data can be stored in an object and unserialised on each request, like so:
Our reusable, serializable object:
[Serializable]
public class UserProfileSessionData
{
public int UserId { get; set; }
public string EmailAddress { get; set; }
public string FullName { get; set; }
}
Use case:
public class LoginController : Controller {
[HttpPost]
public ActionResult Login(LoginModel model)
{
if (ModelState.IsValid)
{
var profileData = new UserProfileSessionData {
UserId = model.UserId,
EmailAddress = model.EmailAddress,
FullName = model.FullName
}
this.Session["UserProfile"] = profileData;
}
}
public ActionResult LoggedInStatusMessage()
{
var profileData = this.Session["UserProfile"] as UserProfileSessionData;
/* From here you could output profileData.FullName to a view and
save yourself unnecessary database calls */
}
}
Once this object has been serialised, we can use it across all controllers without needing to create it or query the database for the data contained within it again.
Inject your session object using Dependency Injection
In a ideal world you would 'program to an interface, not implementation' and inject your serializable session object into your controller using your Inversion of Control container of choice, like so (this example uses StructureMap as it's the one I'm most familiar with).
public class WebsiteRegistry : Registry
{
public WebsiteRegistry()
{
this.For<IUserProfileSessionData>().HybridHttpOrThreadLocalScoped().Use(() => GetUserProfileFromSession());
}
public static IUserProfileSessionData GetUserProfileFromSession()
{
var session = HttpContext.Current.Session;
if (session["UserProfile"] != null)
{
return session["UserProfile"] as IUserProfileSessionData;
}
/* Create new empty session object */
session["UserProfile"] = new UserProfileSessionData();
return session["UserProfile"] as IUserProfileSessionData;
}
}
You would then register this in your Global.asax.cs file.
For those that aren't familiar with injecting session objects, you can find a more in-depth blog post about the subject here.
A word of warning:
It's worth noting that sessions should be kept to a minimum, large sessions can start to cause performance issues.
It's also recommended to not store any sensitive data in them (passwords, etc).
This is how session state works in ASP.NET and ASP.NET MVC:
ASP.NET Session State Overview
Basically, you do this to store a value in the Session object:
Session["FirstName"] = FirstNameTextBox.Text;
To retrieve the value:
var firstName = Session["FirstName"];
You can store any kind of data in a session using:
Session["VariableName"]=value;
This variable will last 20 mins or so.
U can store any value in session like
Session["FirstName"] = FirstNameTextBox.Text;
but i will suggest u to take as static field in model assign value to it and u can access that field value any where in application. U don't need session. session should be avoided.
public class Employee
{
public int UserId { get; set; }
public string EmailAddress { get; set; }
public static string FullName { get; set; }
}
on controller - Employee.FullName = "ABC";
Now u can access this full Name anywhere in application.

Creating history table using Entity Framework 4.1

I am working on asp.net MVC 3 application and I am using codeFirst approach. I am trying to create history table or user table, Where I want to keep track of what columns were modified by user. How can I do this using EF Code First.
Do I need to do it after DataContext.savechanges ?
Please suggest.
Thanks.
The DbContext has a method called Entry<T>:
var entity = context.Items.Find(id);
entity.Name = "foobar";
var entry = context.Entry<Item>(entity);
entry will be of type DbEntityEntry<T> and has the properties OriginalValues and CurrentValues.
You could probably write something that will generically inspect these properties to see what has changed and then automatically insert a new record into your history table.
Either that, or use database triggers.
I'm not sure if this is really the "appropiate" way to do it, but this is how its usually done in sql:
Create an extra property version of type int or something.
Because you probably do not want to loop every time, add another property IsLatestVersion of type bool
When an entity is saved, check if the entity already exists. If so, set the entity on IsLatestVersion = false.
Increment the version, and save the changes as new entity.
Sounds to me like you want an a filter that inherits from ActionFilterAttribute. In my case, this is the simplest example that I have. This is my model, notice that the attributes dictate the mapping to the database.
[Table("UserProfile")]
public class UserProfile
{
[Key, DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int UserId { get; set; }
public string UserName { get; set; }
}
In my case, it was as simple as the following, although it was not historical:
public sealed class UsersContext : DbContext
{
public UsersContext() : base("DefaultConnection")
{
}
public DbSet<UserProfile> UserProfiles { get; set; }
}
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
LazyInitializer.EnsureInitialized(ref _initializer, ref isInitialized, ref initializerLock);
}
public void CheckDatabase()
{
Database.SetInitializer<YourDBContextType>(null);
using (var context = new YourDBContextType())
{
if (!context.Database.Exists())
{
((IObjectContextAdapter)context).ObjectContext.CreateDatabase();
}
}
// Uses your connection string to build the following table.
WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "UserName", autoCreateTables: true);
}
The end result is not only EF being code first, but also allows for your models for your views to use primitives derived from your complex entities. Now, if you have another, lets say historical, DBContext then I would recommend modifying either the text transformation file or creating a base class for your entities. Both ways allow for an easy generation of code that could insert into your table, then follow up with that entity, clone it into a historical model and save. All that being said, I am a fan of database first approaches with concentration on constraints, triggers, etc. instead of a framework.

Resources