4

I have created Empty MVC (ASP.NET Web Application) project using Visual Studio 2013 Update 2 RC & then added AspNet Identity Samples using:

PM>Install-Package Microsoft.AspNet.Identity.Samples -Pre

I have enabled and added migrations & then updated database, which created default tables. enter image description here

I want to create Customer table which contains 2 columns as Foreign Keys to:

  • Groups table (GroupId column)
  • AspNetUsers table (Id column)

So I have created 2 classes Customer & Group and added Foreign Keys using Data-annotations as shown below:

namespace IdentitySample.Models
{
    // You can add profile data for the user by adding more properties to your ApplicationUser class, please visit http://go.microsoft.com/fwlink/?LinkID=317594 to learn more.
    public class ApplicationUser : IdentityUser
    {
        public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
        {
            // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
            var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
            // Add custom user claims here
            return userIdentity;
        }
    }

    public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
    {
        public ApplicationDbContext()
            : base("DefaultConnection", throwIfV1Schema: false)
        {
        }

        static ApplicationDbContext()
        {
            // Set the database intializer which is run once during application start
            // This seeds the database with admin user credentials and admin role
            Database.SetInitializer<ApplicationDbContext>(new ApplicationDbInitializer());
        }

        public static ApplicationDbContext Create()
        {
            return new ApplicationDbContext();
        }
        public DbSet<Customer> Customers { get; set; }
        public DbSet<Group> Groups { get; set; }
    }

    public class Customer
    {
        public int CustomerId { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public int Age { get; set; }
        public int GroupId { get; set; }
        public string CreatedBy { get; set; }



        [ForeignKey("GroupId")]
        public Group Groups { get; set; }

        [ForeignKey("CreatedBy")]
        public ApplicationUser ApplicationUsers { get; set; }
    }

    public class Group
    {
        public int GroupId { get; set; }
        public string GroupName { get; set; }
    }
}

Everything seems fine, the ApplicationDbContext.edmx diagram created using EF Power tools also looks fine & project builds properly.

enter image description here

I have then added CustomersController using "MVC 5 Controller with views, using Entity Framework" scaffolding template.

enter image description here

Now I am getting compilation error (at db.ApplicationUsers)

// GET: Customers/Create
public ActionResult Create()
{
    ViewBag.CreatedBy = new SelectList(db.ApplicationUsers, "Id", "Email");
    ViewBag.GroupId = new SelectList(db.Groups, "GroupId", "GroupName");
    return View();
}

enter image description here

Error details: 'IdentitySample.Models.ApplicationDbContext' does not contain a definition for 'ApplicationUsers' and no extension method 'ApplicationUsers' accepting a first argument of type 'IdentitySample.Models.ApplicationDbContext' could be found (are you missing a using directive or an assembly reference?)

When I add below code in ApplicationDbContext

public DbSet<ApplicationUser> ApplicationUsers { get; set; }

I get error:

Multiple object sets per type are not supported. The object sets 'ApplicationUsers' and 'Users' can both contain instances of type 'IdentitySample.Models.ApplicationUser'

I want to add CreatedBy as foreign key to AspNetUsers, using which the template generate CreatedBy dropdown similar to GroupId dropdown:

enter image description here

How can we use Identity generated tables with other user created tables, where user created table have Foreign Key references to Identity generated tables. And have first class scaffolding code generation experience using "MVC 5 Controller with views, using Entity Framework"?
(Similar to what we have with Customers & Groups table, where Customers table have GroupId Foreign key reference)

2 Answers 2

3

Entity Framework is smart enough to recognize conventional name for IDs/keys. So in order to add a foreign key you would do this:

public class Customer
{
    public string CustomerId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int Age { get; set; }

    public int ApplicationUserId { get; set; }
    public virtual ApplicationUser ApplicationUser { get; set; } 
}

By the convention it matches a class name plus “Id” as a foreign key. If you don't want to use this convention then you can use ForeignKey data annotation to help EF understand what should be the foreign key:

public class Customer
{
    public string CustomerId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int Age { get; set; }

    public int UserId { get; set; }
    [ForeignKey("UserId")]
    public ApplicationUser ApplicationUser { get; set; }
}

Take a look at this and this articles for more info.

Sign up to request clarification or add additional context in comments.

5 Comments

I have tried to add UserId as above but still getting error. I have added images & Group class to explain my question in more detail.
wait, but the question was about correct way of adding foreign keys, now you modified the question? That's not how it's supposed to work. You should've closed your original Q and ask another one. Now you want to do completely different thing from what you've originally asked and my answer becomes irrelevant to those who are really looking for a correct way to add a foreign key.
in regards to your new question, it's all over the place, you're trying to do multiple things at once and ask multiple questions... you'll need to focus on one thing, then move onto another... the way you tried to define ApplicationUsers and Groups in your Customer class is one-to-one relationship, yet you want to create a drop down for them... secondly, when you're scaffolding Customer object and then for some reason you want to create a drop down for ApplicationUser which I don't really get what you're trying to accomplish by doing that, and third, CreatedBy is a string
With the help of info & link you provided, along with Rudi comment, I am able to create the Foreign Key in Customers table and populated the UserIds in dropdown created by the default template.
This answer actually solved a very similar issue for me. Was trying to add ApplicationUser as a foreign key and it wasn't working. Added the [ForeignKey()] attribute to point to the actual foreign key i wanted to use and presto! Worked. Thanks.
2

RTFE: you do not have a property ApplicationUsers on your ApplicationDbContext class.

Just add:

    public DbSet<ApplicationUser> ApplicationUsers { get; set; }

6 Comments

I have tried adding this also, but at RunTime getting error: Multiple object sets per type are not supported. The object sets 'ApplicationUsers' and 'Users' can both contain instances of type 'IdentitySample.Models.ApplicationUser'.
Ah, in that case, you need to use ViewBag.CreatedBy = new SelectList(db.Users, "Id", "Email"); to retrieve the users.
Thank you so much, it works. However, is there any way where CustomersController scaffolding template code add db.Users by default instead of we change db.ApplicationUsers manually?
Rudi, ApplicationUsers it's not supposed to be there, it's already using DBContext underneath ASP.NET Identity...
Is this a right answer? Why mark this...I think it is wrong. Just like @dima says
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.