Including Identity User with Entity Framework doesn't work - asp.net

I am having trouble including my Identity User in query results. Other entities are included just fine, no matter how many levels deep.
Here's the model I'm using.
Building * --- 1 City
* *
| /
| /
1 1
ApplicationUser
And the context:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public DbSet<City> Cities { get; set; }
public DbSet<Building> Buildings { get; set; }
}
Both Building and City have these properties:
public Guid ApplicationUserId { get; set; }
public virtual ApplicationUser ApplicationUser { get; set; }
The query I'm using to retrieve data:
var building = context.Buildings
.Include(c => c.ApplicationUser)
.Include(c => c.City)
.Include(c => c.City.ApplicationUser)
.First();
In the result City is populated just fine, however ApplicationUser is not.
Could this be a naming issue? I've already tried UserId / User and AspNetUserId / AspNetUser as property names without succes.
I'm using Migrations to create the database. The table name that gets created for users is AspNetUsers.
I'm using entity framework 7 beta 7, not sure if this applies to other versions as well.
These are the files generated by EF Migrations.
ApplicationDbContextModelSnapshot.cs
20150929181902_Init.cs
20150929181902_Init.Designer.cs
(I noticed I forgot to include the Building > City relation when generating files for upload, but that shouldn't matter for the example)

I've finally figured it out.
ApplicationUser inherits from IdentityUser which inherits from IdentityUser<string>. The generic type is used as the primary key, so a string!
I changed my Guid foreign key properties to strings and now everything is working.

Just to help anyone who also have a similar issue. I was facing same thing, same scenario: My custom identity user has some related entities and using .Include was not working. None of them would come back. But they used to.
Turns out I had created a custom ApplicationUserStore to automatically include the entities I would normally always need when retrieving a User but I had only overridden FindByIdAsync method. When I tried to use FindByNameAsync no entity would come back, obviously. Just had to override this and the other Find methods.

Related

Ardalis CleanArchitecture - BaseEntity & Composite Keys for AggregateRoots

What is the recommendation for extending BaseEntity as an AggregateRoot is I need to have a composite Key?
Essentially I need to be able to manage an Entity that would normally be configured in EFCore like:
builder.HasKey(z => new { z.PartA, z.PartB });
Currently the template gives us the following definition of BaseEntity, but it's unclear to me how I might need to setup the EntityTypeCuilder config, and how the Aggregates might handle this scenario under the hood.
// This can be modified to BaseEntity<TId> to support multiple key types (e.g. Guid)
public abstract class BaseEntity
{
public int Id { get; set; }
public List<BaseDomainEvent> Events = new List<BaseDomainEvent>();
}
Paul

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.

Cannot drop database. Because it is in currently use. EF Code first approach

I am using code first entity framework approach. I have changed the name Plane_EcoClass to Plane_Class property to the table in the database. It is showing with old property name in the db .How can I update the new property name?. Please let me know how to resolve this error.
public class Plane
{
[Key]
public int Plane_id { get; set; }
public string Plane_Name { get; set; }
public string Plane_No { get; set; }
public string Plane_Class { get; set; }
public virtual List<User>Users { get; set; }
}
you need to add a migration and update the database for the change to affect the database. In the package manager console, type something like:
add-migration YourMigrationName
to create the migration. Review the migration code. Be aware that Entity Framework may try to drop the previously named column and add a column for the new name. This can potentially cause data loss. If this is the case and not desired, then you can manually change the code to use the RenameColumn method.
After adding the migration, you can apply it to the database by going back to the package manager console and typing:
update-database
and then hitting enter. At this point, the package manager console will give you some output regarding running migrations and your seed method and then the database should reflect the updated column name

No key defined. Define the key for this EntityType when implementing interface that has Id

I want to implement an interface defined in Dev Express IResource in my EF Code First business object.
public class JResource : IResource , IXafEntityObject
{
[Key]
public int IdKey { get; set; }
[NotMapped]
public object Id => IdKey; // since IResource wants this.
// other properties
}
When I run my application to create the database I get an error that I need to define the key for this EntityType.
I think the problem is that EF wants to regard Id as the Key but I have made Id NotMapped since I want it to be an Int and the interface wants it to be an object.
Is there a work around?
It turned out that I was using the wrong reference for the [Key] attribute.
The correct one is
System.ComponentModel.DataAnnotations.KeyAttribute

Administration tool MVC3 / MVC4 foreign key

I've made use of the administration tool to create users and roles.
What I'm trying to do is create another table..
public class TaskModel
{
public int Id { get; set; }
public string Time { get; set; }
public string Description{ get; set; }
public class TaskDBContext : DbContext
{
public DbSet<TaskModel> Tasks { get; set; }
}
}
..and create a foreign key to the UserId (Users table) and to the RoleId (Roles table) - (which are both automatically created by the admin tool). The site administration tool does not create models for the tables so I don't know how to point to it and create the foreign keys. (I believe this post described creating FK's between two different classfiles but I cannot apply it: How Should I Declare Foreign Key Relationships Using Code First Entity Framework (4.1) in MVC3?).
Also another question; I know how to display TaskModel records in a view, but how do I filter those results with the foreignkeys in it? What I mean is filter by UserId (logged in user) and/or RoleId? (this question is less important then question above).
You could write a custom membership provider that the website administration tool will use. In your custom membership provider, you will create the records in your extra table, and insert them into the users table when a user is created. If you need any special user interface for this, then you'll have to write your own user administration tool.
http://www.codeproject.com/Articles/165159/Custom-Membership-Providers

Resources