4

I have a MVC 5 application, which uses the Default Identity authentication. The user profile is part of our model, which means that there are several class which have a foreign key to the UserInfo. There are 2 DbContext, one for the model and another for the UserInfo.

 public class ApplicationDbContext : IdentityDbContext<UserInfo>
    {
        public ApplicationDbContext()
            : base("Profile")
        {
        }

    }



 public class UserInfo : IdentityUser
        {
            public UserInfo ()
            {
                LibraryItems = new List<LibraryItem>();
                if (UserGroup == UserGroupEnum.ANALYST)
                {
                    Companies = new List<Company>();
                }
                DateCreate = DateTime.Now;
                DateUpdate = DateTime.Now;
                DateDelete = DateTime.Now;
            }

            [DisplayColumnInIndex]
            [DisplayName("Is Active ?")]
            public bool IsActive { get; set; }

            [Timestamp]
            public byte[] RowVersion { get; set; }

            //[ValidateFile(ErrorMessage = "Please select a PNG image smaller than 1MB")]
            //[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:MM/dd/yyyy}")]
            [Editable(false, AllowInitialValue = true)]
            public DateTime DateCreate { get; set; }

            //[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:MM/dd/yyyy}")]
            public DateTime DateUpdate { get; set; }

            //[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:MM/dd/yyyy}")]
            public DateTime DateDelete { get; set; }

            [DisplayColumnInIndex]
            public String Name { get; set; }
            [DisplayColumnInIndex]
            public String FirstName { get; set; }

            [DisplayColumnInIndex]
            public String Pseudo { get; set; }

            [DisplayColumnInIndex]
            public string PhoneNumber { get; set; }

            [DisplayColumnInIndex]
            public String Company { get; set; }

            [DisplayName("Name_Id")]
            [ForeignKey("FullName")]
            public int? NameId { get; set; }
            [DisplayColumnInIndex]
            public UserGroupEnum UserGroup { get; set; }

            [DisplayColumnInIndex]
            public UserStatusEnum UserStatus { get; set; }

            public virtual Name FullName { get; set; }
    }


public class Comment
{
       // more properties
        [DisplayName("UserInfoId")]
        [ForeignKey("UserInfo")]
        public virtual String UserInfoId { get; set; }
}

public class Like
{
      // more properties
        [DisplayName("UserInfoId")]
        [ForeignKey("UserInfo")]
        public virtual String UserInfoId { get; set; }
}

My userInfo has also foreign keys to the the other tables of the second DBontext.

What is the best way to design our authentication system? and maintain the relationship between the two contexts.

Thanks in advance.

1 Answer 1

7

The solution I came up with recently is to use single context for both ASP.NET identity data and your business entities:

public class DatabaseContext : IdentityDbContext<UserInfo>
{
    public virtual DbSet<Comment> Comments { get; set; } // Your business entities

    public DatabaseContext()
        : base("name=DatabaseContext")
    {
    }
}

Notice that the DatabaseContext inherits from the IdentityDbContext<UserInfo>.

There are some trade-offs with this approach: for example, your data access layer should reference Microsoft.AspNet.Identity.Core and Microsoft.AspNet.Identity.EntityFramework; however, having a single database context in your project makes things much easier if you are using dependency injection or Entity Framework migrations.

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

3 Comments

Indeed. If you're going to have any relationships between your Identity user entity and any other entity, they must all be in the same context. Otherwise, you'd have to do multiple queries, where you do something like get the user from one context and then use the value from the foreign key property to look up the related object in your other context. It's workable, but not the most efficient way to handle things.
Well, no, but for a different reason. If you have any navigation properties on your user entity to the other types you want in a separate context, whoops, they're actually part of the context your user class resides in. Because EF can't manage the relationship unless it owns all the entities involved, it basically creates implicit DbSets for any referenced entities without their own DbSet. That means migrations for that context will create the tables for those related entities, and they can't simultaneously be managed by another context.
Without navigation properties, you have no lazy-loading, so all you actually have to work with is just some value type "foreign key" property.

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.