ASP Net Core: add many to many relationship with IdentityUser

后端 未结 2 1315
清酒与你
清酒与你 2021-01-06 13:31

i need to add a many to many relationship with UserIdentity in asp net core (i.e: a user can have many books and a book can have many user owners)

I have the book c

相关标签:
2条回答
  • 2021-01-06 13:53

    Simple, public string ApplicationUserId { get; set; }

    ApplicationUser has a default key type of string.

    If you do want to use int, simple do:

    public class ApplicationUser : IdentityUser<int>
    

    Be sure to declare this relationship in your DbContext.

    Here's a sample:

    entityTypeBuilder.HasKey(pcp => new { pcp.CurrencyPairId, pcp.IsMain })
                    .HasName("PartialCurrencyPair_CK_CurrencyPairId_IsMain");
    
                entityTypeBuilder.HasOne(pcp => pcp.Currency).WithMany(c => c.PartialCurrencyPairs)
                    .HasForeignKey(pcp => pcp.CurrencyId)
                    .HasConstraintName("PartialCurrencyPairs_Currency_Constraint");
                entityTypeBuilder.HasOne(pcp => pcp.CurrencyPair).WithMany(cp => cp.PartialCurrencyPairs)
                    .HasForeignKey(pcp => pcp.CurrencyPairId)
                    .HasConstraintName("PartialCurrencyPairs_CurrencyPair_Constraint");
    

    EDIT

    You don't have to explicitly define the generics together with the base class (IdentityUser). You simply do this:

    services.AddIdentity<ApplicationUser, Role>()
                    .AddEntityFrameworkStores<NozomiAuthContext>()
                    .AddDefaultTokenProviders();
    

    This assumes Role and ApplicationUser share the same key type of string, where they are overloads of IdentityRole and IdentityUser respectively.

    0 讨论(0)
  • 2021-01-06 14:03

    In your UserBook model class you have used UserId of type int for ApplicationUser but in your ApplicationUser model class you are inheriting IdentityUser where primary key Id is of type string by default, that means your ApplicationUser's Id is of type string. So there will be a primary key type mismatch for Foreignkey in UserBook table.

    Solution-1: If you have no problem to keep ApplicationUser's primary key Id of type string, then just change the UserId type to string in UserBook model class as follows:

    public class UserBook
    {
        public string UserId { get; set; }
        public ApplicationUser ApplicationUser { get; set; }
        public int BookId { get; set; }
        public Book Book { get; set; }
    }
    

    Solution-2: If you want to change ApplicationUser's primary key Id from default string type to int, then specify the key type as int while you are inheriting IdentityUser as follows:

    public class ApplicationUser : IdentityUser<int>
    {
       public ICollection<UserBook> UserBooks { get; set; }
    }
    

    Now you have to make changes in ConfigureServices method of the Startup class as follows:

    services.AddDefaultIdentity<IdentityUser<int>>() // here replace `IdentityUser` with `IdentityUser<int>`
            .AddDefaultUI()
            .AddEntityFrameworkStores<ApplicationDbContext>()
            .AddDefaultTokenProviders();
    

    Now finally your model configuration (for both Solution-1 and Solution-2) using Fluent Api should be as follows:

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<UserBook>()
            .HasKey(ub => new { ub.UserId, ub.BookId });
    
        modelBuilder.Entity<UserBook>()
            .HasOne(ub => ub.ApplicationUser)
            .WithMany(au => au.UserBooks)
            .HasForeignKey(ub => ub.UserId);
    
        modelBuilder.Entity<UserBook>()
            .HasOne(ub => ub.Book)
            .WithMany() // If you add `public ICollection<UserBook> UserBooks { get; set; }` navigation property to Book model class then replace `.WithMany()` with `.WithMany(b => b.UserBooks)`
            .HasForeignKey(ub => ub.BookId);
    }
    
    0 讨论(0)
提交回复
热议问题