MVC 5 EF 6 Identity 2 Многие ко многим с ApplicationUser всегда пустым - PullRequest
0 голосов
/ 28 февраля 2019

У меня есть первое приложение базы данных MVC 5 / EF 6, использующее Identity 2. Модель Identity по умолчанию уже была изменена, чтобы включить UserRoles и несколько пользовательских свойств, сопоставленных со столбцами, которые я добавил в AspNetUsers - все до этого момента работало замечательно.

У меня есть новое требование добавить отношение «многие ко многим» к AspNetUsers под названием AspNetUserAgreements.Я добавил таблицу и внешние ключи в БД.

CREATE TABLE [dbo].[Agreement](
    [AgreementID] [int] IDENTITY(1,1) NOT NULL,
    [HTML] [varchar](max) NULL,
    [Brief] [varchar](500) NULL,
    [CreateDate] [datetime] NOT NULL CONSTRAINT [DF_Agreement_CreateDate]  DEFAULT (getdate()),
    [ChangeDate] [datetime] NULL,
    [Active] [bit] NOT NULL CONSTRAINT [DF_Agreement_Active]  DEFAULT ((1)),
    [UserId] [nvarchar](128) NULL,
    [Name] [varchar](50) NULL,
 CONSTRAINT [PK_Agreement] PRIMARY KEY CLUSTERED 
(
    [AgreementID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO

ALTER TABLE [dbo].[Agreement]  WITH CHECK ADD  CONSTRAINT [FK_Agreement_AspNetUsers] FOREIGN KEY([UserId])
REFERENCES [dbo].[AspNetUsers] ([Id])
GO

ALTER TABLE [dbo].[Agreement] CHECK CONSTRAINT [FK_Agreement_AspNetUsers]
GO

CREATE TABLE [dbo].[AspNetUserAgreement](
    [UserId] [nvarchar](128) NOT NULL,
    [AgreementID] [int] NOT NULL,
 CONSTRAINT [PK_AspNetUserAgreement] PRIMARY KEY CLUSTERED 
(
    [UserId] ASC,
    [AgreementID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

ALTER TABLE [dbo].[AspNetUserAgreement]  WITH CHECK ADD  CONSTRAINT [FK_AspNetUserAgreement_Agreement] FOREIGN KEY([AgreementID])
REFERENCES [dbo].[Agreement] ([AgreementID])
GO

ALTER TABLE [dbo].[AspNetUserAgreement] CHECK CONSTRAINT [FK_AspNetUserAgreement_Agreement]
GO

ALTER TABLE [dbo].[AspNetUserAgreement]  WITH CHECK ADD  CONSTRAINT [FK_AspNetUserAgreement_AspNetUsers] FOREIGN KEY([UserId])
REFERENCES [dbo].[AspNetUsers] ([Id])
GO

ALTER TABLE [dbo].[AspNetUserAgreement] CHECK CONSTRAINT [FK_AspNetUserAgreement_AspNetUsers]
GO

У меня есть запись Соглашения, запись AspNetUser и запись aspnetUserAgreement, которая их связывает.Эти 3 таблицы импортированы в модель EF, и я могу видеть список соглашений от объекта AspNetUer, а также видеть список AspNetUsers от объекта соглашения.

ApplicationDbContext OnModelCreating имеет следующее:

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<AspNetUser>()
                .ToTable("AspNetUser")
                .HasKey(d => d.Id)
                .HasMany(d => d.UserAgreements)
                .WithMany(d => d.AspNetUsers)
                .Map(m =>
                {
                    m.MapLeftKey("Id");
                    m.MapRightKey("AgreementID");
                });

            modelBuilder.Entity<ApplicationUser>()
                .HasMany(d => d.UserAgreements)
                .WithMany(d => d.ApplicationUsers)
                .Map(m =>
                {
                    m.MapLeftKey("Id");
                    m.MapRightKey("AgreementID")
                });


            modelBuilder.Entity<ApplicationUserRole>()//.ToTable("ApplicationUserRole")
                .HasKey(ur => new { ur.UserId, ur.RoleId });
            modelBuilder.Entity<ApplicationUserRole>()
                .HasRequired(r => r.Role)
                .WithMany(r => r.UserRoles)
                .HasForeignKey(ur => ur.RoleId);
            modelBuilder.Entity<ApplicationUserRole>()//.ToTable("ApplicationRole")
                .HasRequired(ur => ur.User)
                .WithMany(r => r.UserRoles)
                .HasForeignKey(ur => ur.UserId);

            base.OnModelCreating(modelBuilder);
        }

ApplicationUser имеет следующее:

    public class ApplicationUser : IdentityUser<string, IdentityUserLogin, ApplicationUserRole, IdentityUserClaim>
    {
        public ApplicationUser()
        {
            UserAgreements = new HashSet<Agreement>();
            UserRoles = new List<ApplicationUserRole>();
            Id = Guid.NewGuid().ToString();
        }

        public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser, string> 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
            if (MemberDirectoryID.HasValue)
            {

            userIdentity.AddClaim(new Claim("Toolbar", this.Toolbar));
            userIdentity.AddClaim(new Claim("HasSignedAgreement", this.HasSignedAgreement.ToString()));
            //userIdentity.AddClaim(new Claim("NewMemberTemporaryGUID", this.NewMemberTemporaryGUID));
            return userIdentity;
        }

        public string Toolbar
        {
            get
            {
                 return ((List<ApplicationUserRole>)UserRoles).Any(a => a.Role.Name == "Admin") ? "admin" : "member";
            }
        }

        public bool HasSignedAgreement
        {
            get
            {
                return ((HashSet<Agreement>)UserAgreements).Any();
            }
        }

        public ICollection<ApplicationUserRole> UserRoles { get; set; }
        public ICollection<Agreement> UserAgreements { get; set; }

    }

Объект соглашения создан EF, но у меня есть этот частичный класс для его расширения:

    public interface IAgreement
    {
    }

    [MetadataType(typeof(IAgreement))]
    public partial class Agreement : IAgreement
    {
        public virtual ICollection<ApplicationUser> ApplicationUsers { get; set; } = new HashSet<ApplicationUser>();
    }

Мне нужен код идентификации, чтобы вернуть моему ApplicationUser со списком пользовательских соглашений, заполненных соглашениями.Это должно быть сделано изначально при входе в систему, потому что есть специальный атрибут фильтра, который проверяет количество UserAgreements, а затем направляет пользователя в зависимости от значения.

Оператор задачи: При вызове Identityобъекты кажутся правильно структурированными, т.е. у моего ApplicationUser есть коллекция соглашений, называемых UserAgreements, но она пуста.Нет ошибок, нет данных.Соглашения никогда не загружаются ... Я, должно быть, что-то упускаю, так как, если я вызываю модельный контекст, я могу получить Соглашения от AspNetUser и я могу получить ApplicationUsers из Соглашения.

Любая помощь приветствуется, спасибо!

...