Administration tool MVC3 / MVC4 foreign key - asp.net

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

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.

Insert record with relationship using OData

This is what my models looks like
public User
{
public string Id { get; set; }
public string Username { get; set; }
public virtual Group Group { get; set; }
}
public Group
{
public string Id { get; set; }
public string Name{ get; set; }
public virtual ICollection<User> Users { get; set; }
}
I using Azure Mobile TableController which using OData for CRUD.
Now I trying to insert new user by specifying the id of the group but instead it gives me an error which shows that instead of trying to associate it with my user model it trying to create new one:
{
"message": "The operation failed due to a conflict: 'Violation of PRIMARY KEY constraint 'PK_dbo.Groups'. Cannot insert duplicate key in object 'dbo.Groups'. The duplicate key value is (ad934511a82c4b42ae5427b5228737c6).\r\nThe statement has been terminated.'."
}
This is what my post looks like:
POST http://localhost/tables/user?ZUMO-API-VERSION=2.0.0 HTTP/1.1
{
email: 'test#test.com',
password: '#test',
group: {
id: 'ad934511a82c4b42ae5427b5228737c6'
}
}
Relationships are not directly supported in Azure Mobile Apps, but you can apply some workarounds to get it to work. Here's a blog post that walks through the scenario: 30 Days of Zumo.v2 (Azure Mobile Apps): Day 26: Relationship Advice.
The specific problem you're running into is the Entity Framework "detatched entities" problem. See e.g. Many to Many Relationships not saving. The problem is that Entity Framework has not loaded the child item into its context, so it thinks that it needs to insert the child item as well as the parent. (There have been long-standing feature requests in Entity Framework to solve this, but the feature has never been added.)
I just posted a similar answer here: How do I insert entities with a 1:n relationship in Azure App Service

Including Identity User with Entity Framework doesn't work

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.

Entity Framework 4.1 Code First: Advice on persisting data from external source?

Part of my project is to persist data from another source. In this case we have an SAP data source that we will need to pull data from. I need to take the data from SAP and map it to entities I have in my application. Here is an example of an entity I have in my application:
public class Project : BaseEntity
{
public string Name { get; set; }
public string ProjectNumber { get; set; }
public string Description { get; set; }
public string CreatedBy { get; set; }
public string ModifiedBy { get; set; }
public string Currency { get; set; }
#region Navigation Properties
public virtual Address Address { get; set; }
public virtual CompanyCode CompanyCode { get; set; }
public virtual ICollection<Contact> TeamMembers { get; set; }
#endregion
}
As you can see, I have child objects that I map from SAP as well. I need some advice on the best way to insert and update my entities. I am struggling with knowing when to add (insert) entities to my context and when to attach (update) them, because SAP doesn't have knowledge of what my application may or may not have. I need to guard against duplicates, too. For example, should I perform a lookup of each child entity in my parent entity to see if they exist before I apply them to the parent? Then, add / attach the entire parent object to the context or handle each entity separately while still maintaing their relationships?
Yes you must manually test everything to make correct decision what must be inserted, updated or deleted. Depending on the application you can use some more complex queries to reduce number of round trips to the database - for example you can use single query with Contains to load all TeamMembers needed for processed Project or you can load Project with including all related data if you also need to test if project exists.
I did large synchronization application before and I end up with pre-loading all entities at the beginning with few queries and working completely in memory.
Don't forget to use DbSet's Local property or Find method to take advantage of already loaded entities.
You can also use some custom stored procedures to improve performance of this operation.

Resources