EntityType 'IdentityUserLogin' không có khóa nào được xác định. Xác định khóa cho EntityType này


105

Tôi đang làm việc với Entity Framework Code First và MVC 5. Khi tôi tạo ứng dụng của mình với Xác thực Tài khoản Người dùng Cá nhân, tôi đã được cấp một bộ điều khiển Tài khoản và cùng với nó là tất cả các lớp và mã bắt buộc cần thiết để xác thực Tài khoản Người dùng Indiv hoạt động .

Trong số các mã đã có là:

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

    }

    public static ApplicationDbContext Create()
    {
        return new ApplicationDbContext();
    }
}

Nhưng sau đó tôi đã tiếp tục và tạo ngữ cảnh của riêng mình bằng cách sử dụng mã trước, vì vậy bây giờ tôi cũng có những thứ sau:

public class DXContext : DbContext
{
    public DXContext() : base("DXContext")
    {
        
    }

    public DbSet<ApplicationUser> Users { get; set; }
    public DbSet<IdentityRole> Roles { get; set; }
    public DbSet<Artist> Artists { get; set; }
    public DbSet<Paintings> Paintings { get; set; }        
}

Cuối cùng, tôi có phương pháp hạt giống sau để thêm một số dữ liệu để tôi làm việc trong khi phát triển:

protected override void Seed(DXContext context)
{
    try
    {

        if (!context.Roles.Any(r => r.Name == "Admin"))
        {
            var store = new RoleStore<IdentityRole>(context);
            var manager = new RoleManager<IdentityRole>(store);
            var role = new IdentityRole { Name = "Admin" };

            manager.Create(role);
        }

        context.SaveChanges();

        if (!context.Users.Any(u => u.UserName == "James"))
        {
            var store = new UserStore<ApplicationUser>(context);
            var manager = new UserManager<ApplicationUser>(store);
            var user = new ApplicationUser { UserName = "James" };

            manager.Create(user, "ChangeAsap1@");
            manager.AddToRole(user.Id, "Admin");
        }

        context.SaveChanges();

        string userId = "";

        userId = context.Users.FirstOrDefault().Id;

        var artists = new List<Artist>
        {
            new Artist { FName = "Salvador", LName = "Dali", ImgURL = "http://i62.tinypic.com/ss8txxn.jpg", UrlFriendly = "salvador-dali", Verified = true, ApplicationUserId = userId },
        };

        artists.ForEach(a => context.Artists.Add(a));
        context.SaveChanges();

        var paintings = new List<Painting>
        {
            new Painting { Title = "The Persistence of Memory", ImgUrl = "http://i62.tinypic.com/xx8tssn.jpg", ArtistId = 1, Verified = true, ApplicationUserId = userId }
        };

        paintings.ForEach(p => context.Paintings.Add(p));
        context.SaveChanges();
    }
    catch (DbEntityValidationException ex)
    {
        foreach (var validationErrors in ex.EntityValidationErrors)
        {
            foreach (var validationError in validationErrors.ValidationErrors)
            {
                Trace.TraceInformation("Property: {0} Error: {1}", validationError.PropertyName, validationError.ErrorMessage);
            }
        }
    }
    
}

Giải pháp của tôi xây dựng tốt, nhưng khi tôi thử và truy cập bộ điều khiển yêu cầu quyền truy cập vào cơ sở dữ liệu, tôi gặp lỗi sau:

DX.DOMAIN.Context.IdentityUserLogin:: EntityType 'IdentityUserLogin' không có khóa nào được xác định. Xác định khóa cho EntityType này.

DX.DOMAIN.Context.IdentityUserRole:: EntityType 'IdentityUserRole' không có khóa nào được xác định. Xác định khóa cho EntityType này.

Tôi đang làm gì sai? Có phải vì tôi có hai bối cảnh?

CẬP NHẬT

Sau khi đọc câu trả lời của Augusto, tôi đã chọn Phương án 3 . Đây là lớp DXContext của tôi bây giờ trông như thế nào:

public class DXContext : DbContext
{
    public DXContext() : base("DXContext")
    {
        // remove default initializer
        Database.SetInitializer<DXContext>(null);
        Configuration.LazyLoadingEnabled = false;
        Configuration.ProxyCreationEnabled = false;

    }

    public DbSet<User> Users { get; set; }
    public DbSet<Role> Roles { get; set; }
    public DbSet<Artist> Artists { get; set; }
    public DbSet<Painting> Paintings { get; set; }

    public static DXContext Create()
    {
        return new DXContext();
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        modelBuilder.Entity<User>().ToTable("Users");
        modelBuilder.Entity<Role>().ToTable("Roles");
    }

    public DbQuery<T> Query<T>() where T : class
    {
        return Set<T>().AsNoTracking();
    }
}

Tôi cũng đã thêm một User.csvà một Role.cslớp, chúng trông như thế này:

public class User
{
    public int Id { get; set; }
    public string FName { get; set; }
    public string LName { get; set; }
}

public class Role
{
    public int Id { set; get; }
    public string Name { set; get; }
}

Tôi không chắc liệu mình có cần thuộc tính mật khẩu cho người dùng hay không, vì ApplicationUser mặc định có thuộc tính đó và một loạt các trường khác!

Tuy nhiên, thay đổi ở trên xây dựng tốt, nhưng một lần nữa tôi gặp lỗi này khi ứng dụng được chạy:

Tên cột không hợp lệ UserId

UserId là một thuộc tính số nguyên trên của tôi Artist.cs

Câu trả lời:


116

Vấn đề là ApplicationUser của bạn kế thừa từ IdentityUser , được định nghĩa như sau:

IdentityUser : IdentityUser<string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>, IUser
....
public virtual ICollection<TRole> Roles { get; private set; }
public virtual ICollection<TClaim> Claims { get; private set; }
public virtual ICollection<TLogin> Logins { get; private set; }

và các khóa chính của chúng được ánh xạ trong phương thức OnModelCreating của lớp IdentityDbContext :

modelBuilder.Entity<TUserRole>()
            .HasKey(r => new {r.UserId, r.RoleId})
            .ToTable("AspNetUserRoles");

modelBuilder.Entity<TUserLogin>()
            .HasKey(l => new {l.LoginProvider, l.ProviderKey, l.UserId})
            .ToTable("AspNetUserLogins");

và vì DXContext của bạn không xuất phát từ nó, các khóa đó không được xác định.

Nếu bạn tìm hiểu các nguồn củaMicrosoft.AspNet.Identity.EntityFramework , bạn sẽ hiểu mọi thứ.

Tôi đã gặp tình huống này một thời gian trước và tôi đã tìm thấy ba giải pháp khả thi (có thể có nhiều hơn):

  1. Sử dụng DbContexts riêng biệt với hai cơ sở dữ liệu khác nhau hoặc cùng một cơ sở dữ liệu nhưng các bảng khác nhau.
  2. Hợp nhất DXContext của bạn với ApplicationDbContext và sử dụng một cơ sở dữ liệu.
  3. Sử dụng các DbContexts riêng biệt trên cùng một bảng và quản lý quá trình di chuyển của chúng cho phù hợp.

Tùy chọn 1: Xem cập nhật ở dưới cùng.

Tùy chọn 2: Bạn sẽ kết thúc với một DbContext như thế này:

public class DXContext : IdentityDbContext<User, Role,
    int, UserLogin, UserRole, UserClaim>//: DbContext
{
    public DXContext()
        : base("name=DXContext")
    {
        Database.SetInitializer<DXContext>(null);// Remove default initializer
        Configuration.ProxyCreationEnabled = false;
        Configuration.LazyLoadingEnabled = false;
    }

    public static DXContext Create()
    {
        return new DXContext();
    }

    //Identity and Authorization
    public DbSet<UserLogin> UserLogins { get; set; }
    public DbSet<UserClaim> UserClaims { get; set; }
    public DbSet<UserRole> UserRoles { get; set; }
    
    // ... your custom DbSets
    public DbSet<RoleOperation> RoleOperations { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
        modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();

        // Configure Asp Net Identity Tables
        modelBuilder.Entity<User>().ToTable("User");
        modelBuilder.Entity<User>().Property(u => u.PasswordHash).HasMaxLength(500);
        modelBuilder.Entity<User>().Property(u => u.Stamp).HasMaxLength(500);
        modelBuilder.Entity<User>().Property(u => u.PhoneNumber).HasMaxLength(50);

        modelBuilder.Entity<Role>().ToTable("Role");
        modelBuilder.Entity<UserRole>().ToTable("UserRole");
        modelBuilder.Entity<UserLogin>().ToTable("UserLogin");
        modelBuilder.Entity<UserClaim>().ToTable("UserClaim");
        modelBuilder.Entity<UserClaim>().Property(u => u.ClaimType).HasMaxLength(150);
        modelBuilder.Entity<UserClaim>().Property(u => u.ClaimValue).HasMaxLength(500);
    }
}

Tùy chọn 3: Bạn sẽ có một DbContext bằng với tùy chọn 2. Hãy đặt tên nó là IdentityContext. Và bạn sẽ có một DbContext khác được gọi là DXContext:

public class DXContext : DbContext
{        
    public DXContext()
        : base("name=DXContext") // connection string in the application configuration file.
    {
        Database.SetInitializer<DXContext>(null); // Remove default initializer
        Configuration.LazyLoadingEnabled = false;
        Configuration.ProxyCreationEnabled = false;
    }

    // Domain Model
    public DbSet<User> Users { get; set; }
    // ... other custom DbSets
    
    public static DXContext Create()
    {
        return new DXContext();
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();

        // IMPORTANT: we are mapping the entity User to the same table as the entity ApplicationUser
        modelBuilder.Entity<User>().ToTable("User"); 
    }

    public DbQuery<T> Query<T>() where T : class
    {
        return Set<T>().AsNoTracking();
    }
}

nơi Người dùng ở:

public class User
{
    public int Id { get; set; }

    [Required, StringLength(100)]
    public string Name { get; set; }

    [Required, StringLength(128)]
    public string SomeOtherColumn { get; set; }
}

Với giải pháp này, tôi đang ánh xạ thực thể Người dùng vào cùng một bảng với thực thể ApplicationUser.

Sau đó, bằng cách sử dụng Code First Migrations, bạn sẽ cần tạo các lần di chuyển cho IdentityContext và THEN cho DXContext, theo dõi bài đăng tuyệt vời này từ Shailendra Chauhan: Code First Migrations với Multiple Data Contexts

Bạn sẽ phải sửa đổi quá trình di chuyển được tạo cho DXContext. Một cái gì đó như thế này tùy thuộc vào thuộc tính nào được chia sẻ giữa Người dùng ứng dụng và Người dùng:

        //CreateTable(
        //    "dbo.User",
        //    c => new
        //        {
        //            Id = c.Int(nullable: false, identity: true),
        //            Name = c.String(nullable: false, maxLength: 100),
        //            SomeOtherColumn = c.String(nullable: false, maxLength: 128),
        //        })
        //    .PrimaryKey(t => t.Id);
        AddColumn("dbo.User", "SomeOtherColumn", c => c.String(nullable: false, maxLength: 128));

và sau đó chạy di chuyển theo thứ tự (đầu tiên là di chuyển Identity) từ global.asax hoặc bất kỳ nơi nào khác trong ứng dụng của bạn bằng cách sử dụng lớp tùy chỉnh này:

public static class DXDatabaseMigrator
{
    public static string ExecuteMigrations()
    {
        return string.Format("Identity migrations: {0}. DX migrations: {1}.", ExecuteIdentityMigrations(),
            ExecuteDXMigrations());
    }

    private static string ExecuteIdentityMigrations()
    {
        IdentityMigrationConfiguration configuration = new IdentityMigrationConfiguration();
        return RunMigrations(configuration);
    }

    private static string ExecuteDXMigrations()
    {
        DXMigrationConfiguration configuration = new DXMigrationConfiguration();
        return RunMigrations(configuration);
    }

    private static string RunMigrations(DbMigrationsConfiguration configuration)
    {
        List<string> pendingMigrations;
        try
        {
            DbMigrator migrator = new DbMigrator(configuration);
            pendingMigrations = migrator.GetPendingMigrations().ToList(); // Just to be able to log which migrations were executed

            if (pendingMigrations.Any())                
                    migrator.Update();     
        }
        catch (Exception e)
        {
            ExceptionManager.LogException(e);
            return e.Message;
        }
        return !pendingMigrations.Any() ? "None" : string.Join(", ", pendingMigrations);
    }
}

Bằng cách này, các thực thể cắt chéo n-tier của tôi cuối cùng không kế thừa từ các lớp AspNetIdentity, và do đó tôi không phải nhập khuôn khổ này trong mọi dự án mà tôi sử dụng chúng.

Xin lỗi cho bài viết rộng rãi. Tôi hy vọng nó có thể cung cấp một số hướng dẫn về điều này. Tôi đã sử dụng tùy chọn 2 và 3 trong môi trường sản xuất.

CẬP NHẬT: Mở rộng Tùy chọn 1

Đối với hai dự án gần đây nhất, tôi đã sử dụng tùy chọn thứ nhất: có một lớp AspNetUser dẫn xuất từ ​​IdentityUser và một lớp tùy chỉnh riêng biệt được gọi là AppUser. Trong trường hợp của tôi, DbContexts lần lượt là IdentityContext và DomainContext. Và tôi đã xác định Id của AppUser như thế này:

public class AppUser : TrackableEntity
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
    // This Id is equal to the Id in the AspNetUser table and it's manually set.
    public override int Id { get; set; }

(TrackableEntity là lớp cơ sở trừu tượng tùy chỉnh mà tôi sử dụng trong phương thức SaveChanges bị ghi đè của ngữ cảnh DomainContext của tôi)

Đầu tiên tôi tạo AspNetUser và sau đó là AppUser. Hạn chế của cách tiếp cận này là bạn phải đảm bảo rằng chức năng "CreateUser" của bạn là giao dịch (hãy nhớ rằng sẽ có hai DbContexts gọi SaveChanges riêng biệt). Việc sử dụng TransactionScope không hiệu quả với tôi vì một số lý do, vì vậy tôi đã kết thúc một việc xấu xí nhưng điều đó phù hợp với tôi:

        IdentityResult identityResult = UserManager.Create(aspNetUser, model.Password);

        if (!identityResult.Succeeded)
            throw new TechnicalException("User creation didn't succeed", new LogObjectException(result));

        AppUser appUser;
        try
        {
            appUser = RegisterInAppUserTable(model, aspNetUser);
        }
        catch (Exception)
        {
            // Roll back
            UserManager.Delete(aspNetUser);
            throw;
        }

(Xin vui lòng, nếu ai đó đưa ra một cách tốt hơn để thực hiện phần này, tôi đánh giá cao việc bình luận hoặc đề xuất chỉnh sửa cho câu trả lời này)

Lợi ích là bạn không phải sửa đổi các di chuyển và bạn có thể sử dụng bất kỳ hệ thống phân cấp kế thừa điên rồ nào đối với AppUser mà không gây rắc rối với AspNetUser . Và trên thực tế, tôi sử dụng Tự động di chuyển cho IdentityContext của mình (ngữ cảnh bắt nguồn từ IdentityDbContext):

public sealed class IdentityMigrationConfiguration : DbMigrationsConfiguration<IdentityContext>
{
    public IdentityMigrationConfiguration()
    {
        AutomaticMigrationsEnabled = true;
        AutomaticMigrationDataLossAllowed = false;
    }

    protected override void Seed(IdentityContext context)
    {
    }
}

Cách tiếp cận này cũng có lợi ích là tránh để các thực thể xuyên suốt cấp n của bạn kế thừa từ các lớp AspNetIdentity.


Cảm ơn @Augusto về bài đăng rộng rãi. Người ta có phải sử dụng Migrations để Tùy chọn 3 hoạt động không? Theo như tôi biết, EF Migrations là để quay lại các thay đổi? Nếu tôi bỏ cơ sở dữ liệu của mình, sau đó tạo lại và gieo nó vào mỗi bản dựng mới, tôi có cần thực hiện tất cả những thứ di chuyển đó không?
J86

Tôi đã không thử nó mà không sử dụng di chuyển. Tôi không biết liệu bạn có thể thực hiện được điều đó mà không sử dụng chúng hay không. Có lẽ nó có thể. Tôi luôn phải sử dụng di chuyển để giữ lại bất kỳ dữ liệu tùy chỉnh nào đã được chèn vào cơ sở dữ liệu.
Augusto Barreto

Một điều cần lưu ý, nếu bạn sử dụng Migrations ... bạn nên sử dụng cái AddOrUpdate(new EntityObject { shoes = green})gọi là "upert". trái ngược với việc chỉ thêm vào ngữ cảnh, nếu không bạn sẽ chỉ tạo thông tin ngữ cảnh thực thể trùng lặp / dư thừa.
Chef_Code

Tôi muốn làm việc với tùy chọn thứ 3, nhưng tôi không hiểu. ai đó có thể vui lòng cho tôi biết chính xác IdentityContext sẽ trông như thế nào không? vì nó không thể giống như trong tùy chọn 2! Bạn có thể giúp tôi @AugustoBarreto được không? Tôi đã thực hiện một chủ đề về một cái gì đó tương tự, có thể bạn có thể giúp tôi có
Arianit

'TrackableEntity' của bạn trông như thế nào?
Ciaran Gallagher

224

Trong trường hợp của tôi, tôi đã kế thừa chính xác từ IdentityDbContext (với các loại tùy chỉnh và khóa của riêng tôi được xác định) nhưng đã vô tình loại bỏ lệnh gọi đến OnModelCreating của lớp cơ sở:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    base.OnModelCreating(modelBuilder); // I had removed this
    /// Rest of on model creating here.
}

Sau đó, việc này đã sửa các chỉ mục còn thiếu của tôi từ các lớp nhận dạng và sau đó tôi có thể tạo các di chuyển và kích hoạt di chuyển một cách thích hợp.


Đã có cùng một vấn đề "loại bỏ dòng". Giải pháp của bạn đã hiệu quả. :) ty.
Nhà phát triển Marius Žilėnas

2
Điều này đã khắc phục sự cố của tôi, trong đó tôi phải ghi đè phương thức OnModelCreating để đưa vào Bản đồ tùy chỉnh bằng cách sử dụng api thông thạo cho mối quan hệ thực thể phức tạp. Hóa ra tôi đã quên thêm dòng trong câu trả lời trước khi khai báo ánh xạ của mình vì tôi đang sử dụng cùng ngữ cảnh với Identity. Chúc mừng.
Dan

Nó hoạt động nếu không có 'ghi đè void OnModelCreating' nhưng nếu bạn ghi đè, bạn cần thêm 'base.OnModelCreating (modelBuilder);' để ghi đè. Đã khắc phục sự cố của tôi.
Joe

13

Đối với những người sử dụng ASP.NET Identity 2.1 và đã thay đổi khóa chính từ khóa mặc định stringthành inthoặc Guid, nếu bạn vẫn nhận được

EntityType 'xxxxUserLogin' không có khóa nào được xác định. Xác định khóa cho EntityType này.

EntityType 'xxxxUserRole' không có khóa nào được xác định. Xác định khóa cho EntityType này.

có thể bạn vừa quên chỉ định loại khóa mới trên IdentityDbContext:

public class AppIdentityDbContext : IdentityDbContext<
    AppUser, AppRole, int, AppUserLogin, AppUserRole, AppUserClaim>
{
    public AppIdentityDbContext()
        : base("MY_CONNECTION_STRING")
    {
    }
    ......
}

Nếu bạn chỉ có

public class AppIdentityDbContext : IdentityDbContext
{
    ......
}

hoặc thậm chí

public class AppIdentityDbContext : IdentityDbContext<AppUser>
{
    ......
}

bạn sẽ gặp lỗi 'không có khóa được xác định' khi bạn đang cố gắng thêm di chuyển hoặc cập nhật cơ sở dữ liệu.


Tôi cũng đang cố gắng thay đổi ID thành Int và đang gặp sự cố này, tuy nhiên tôi đã thay đổi DbContext của mình để chỉ định loại khóa mới. Có nơi nào khác tôi nên kiểm tra không? Tôi nghĩ rằng tôi đã làm theo hướng dẫn rất cẩn thận.
Kyle

1
@Kyle: Bạn đang cố gắng thay đổi ID của tất cả các thực thể thành int, tức là AppRole, AppUser, AppUserClaim, AppUserLogin và AppUserRole? Nếu vậy, bạn cũng có thể cần đảm bảo rằng bạn đã chỉ định loại khóa mới cho các lớp đó. Giống như 'public class AppUserLogin: IdentityUserLogin <int> {}'
David Liang

1
Đây là tài liệu chính thức về tùy chỉnh loại dữ liệu khóa chính: docs.microsoft.com/en-us/aspnet/core/security/authentication/…
AdrienTorris

1
Có, vấn đề của tôi là, tôi kế thừa từ lớp DbContext chung thay vì IdentityDbContext <AppUser>. Cảm ơn, điều này đã giúp ích rất nhiều
thấy

13

Bằng cách thay đổi DbContext như bên dưới;

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
        modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();
    }

Chỉ cần thêm vào OnModelCreatingcuộc gọi phương thức đến base.OnModelCreating (modelBuilder); và nó trở nên tốt đẹp. Tôi đang sử dụng EF6.

Đặc biệt cảm ơn # The Senator


1
 protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);

            //foreach (var relationship in modelBuilder.Model.GetEntityTypes().SelectMany(e => e.GetForeignKeys()))
            //    relationship.DeleteBehavior = DeleteBehavior.Restrict;

            modelBuilder.Entity<User>().ToTable("Users");

            modelBuilder.Entity<IdentityRole<string>>().ToTable("Roles");
            modelBuilder.Entity<IdentityUserToken<string>>().ToTable("UserTokens");
            modelBuilder.Entity<IdentityUserClaim<string>>().ToTable("UserClaims");
            modelBuilder.Entity<IdentityUserLogin<string>>().ToTable("UserLogins");
            modelBuilder.Entity<IdentityRoleClaim<string>>().ToTable("RoleClaims");
            modelBuilder.Entity<IdentityUserRole<string>>().ToTable("UserRoles");

        }
    }

0

Vấn đề của tôi cũng tương tự - tôi có một bảng mới mà tôi đang tạo ahd đó để liên kết với người dùng danh tính. Sau khi đọc các câu trả lời ở trên, nhận ra rằng nó liên quan đến IsdentityUser và các properites kế thừa. Tôi đã thiết lập Identity làm Ngữ cảnh của riêng nó, vì vậy, để tránh việc buộc cả hai với nhau, thay vì sử dụng bảng người dùng có liên quan làm thuộc tính EF thực sự, tôi thiết lập thuộc tính không được ánh xạ với truy vấn để lấy các thực thể có liên quan. (DataManager được thiết lập để truy xuất ngữ cảnh hiện tại mà OtherEntity tồn tại.)

    [Table("UserOtherEntity")]
        public partial class UserOtherEntity
        {
            public Guid UserOtherEntityId { get; set; }
            [Required]
            [StringLength(128)]
            public string UserId { get; set; }
            [Required]
            public Guid OtherEntityId { get; set; }
            public virtual OtherEntity OtherEntity { get; set; }
        }

    public partial class UserOtherEntity : DataManager
        {
            public static IEnumerable<OtherEntity> GetOtherEntitiesByUserId(string userId)
            {
                return Connect2Context.UserOtherEntities.Where(ue => ue.UserId == userId).Select(ue => ue.OtherEntity);
            }
        }

public partial 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;
        }

        [NotMapped]
        public IEnumerable<OtherEntity> OtherEntities
        {
            get
            {
                return UserOtherEntities.GetOtherEntitiesByUserId(this.Id);
            }
        }
    }
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.