C# 为数据层中的实体添加与.NET Identity ApplicationUser的关系
我正在构建一个带有用户登录标识的.NETMVC应用程序。该应用程序有四个层C# 为数据层中的实体添加与.NET Identity ApplicationUser的关系,c#,asp.net-mvc,entity-framework,oop,asp.net-identity,C#,Asp.net Mvc,Entity Framework,Oop,Asp.net Identity,我正在构建一个带有用户登录标识的.NETMVC应用程序。该应用程序有四个层 Web/UI层,引用了我的域和服务层 域层,没有引用 服务层,引用了我的数据层和域层 数据层,引用了我的域层 我希望我的AppUser类与我的数据层中的一个实体公司有关系 AppUser类位于我的域层,它从IdentityUser继承。我之所以将我的AppUser类放在域层中,是因为我需要从Web/UI层访问它,而IdentityConfig需要该类 但是,当我现在想在数据层中为实体添加关系时,事情就变得棘手起来 A
- Web/UI层,引用了我的域和服务层
- 域层,没有引用
- 服务层,引用了我的数据层和域层
- 数据层,引用了我的域层
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using System.Security.Claims;
using System.Threading.Tasks;
namespace ITKA.Domain.Classes
{
public class AppUser : IdentityUser
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string ContactNumber { get; set; }
public int CompanyId { get; set; }
public Company Company { get; set; }
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<AppUser> manager)
{
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
return userIdentity;
}
public void Dispose()
{
}
}
}
using ITKA.Data.Interfaces;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace ITKA.Data.Entities
{
[Table("CompanyTbl")]
public class Company : IEntity
{
[Key]
public int Id { get; set; }
[StringLength(100)]
public string CompanyName { get; set; }
public virtual ICollection<InventoryItem> InventoryItems { get; set; }
}
}
它是否会与公司建立关系
当IdentityConfig需要同样驻留在数据层中的DbContext类时,我遇到了麻烦,但我可以通过使用域层中的接口来解决这个问题
我真的被困在这里,不知道如何解决这个问题。非常感谢您的帮助。如果您将数据层添加到域层引用中,我发现您在开始使用循环引用时遇到了问题。您不希望域和数据相互引用 删除此引用:
- 数据层,引用了我的域层
- 域层,没有引用
Web -> Domain -> Data
-> Service -> Data
-> Domain
AppUser
类保留在域层中
由于第2点,域层引用了数据层,您现在可以使用公司
实体
AppUser.cs
using System;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin;
using Microsoft.Owin.Security;
using ITKA.Domain.Classes;
using ITKA.Domain.Interfaces;
namespace ITKA.Web
{
public class AppUserManager : UserManager<AppUser>
{
public AppUserManager(IUserStore<AppUser> userStore)
: base(userStore)
{
}
public static AppUserManager Create(IdentityFactoryOptions<AppUserManager> options, IOwinContext context)
{
var userStore = new UserStore<AppUser>((IdentityDbContext<AppUser>)context.Get<IITKAContext>());
var manager = new AppUserManager(userStore);
manager.UserValidator = new UserValidator<AppUser>(manager)
{
AllowOnlyAlphanumericUserNames = false,
RequireUniqueEmail = true
};
manager.PasswordValidator = new PasswordValidator
{
RequiredLength = 8,
RequireNonLetterOrDigit = false,
RequireDigit = true,
RequireLowercase = true,
RequireUppercase = true
};
manager.UserLockoutEnabledByDefault = false;
manager.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5);
manager.MaxFailedAccessAttemptsBeforeLockout = 5;
return manager;
}
}
public class AppSignInManager : SignInManager<AppUser, string>
{
public AppSignInManager(AppUserManager userManager,
IAuthenticationManager authManager)
: base(userManager, authManager) { }
public static AppSignInManager Create
(IdentityFactoryOptions<AppSignInManager> options, IOwinContext context)
{
return new AppSignInManager(context.Get<AppUserManager>(),
context.Authentication);
}
}
public class AppRoleManager : RoleManager<IdentityRole>
{
public AppRoleManager(RoleStore<IdentityRole> roleStore)
: base(roleStore) { }
public static AppRoleManager Create(IOwinContext context)
{
var roleStore = new RoleStore<IdentityRole>
((IdentityDbContext<AppUser>)context.Get<IITKAContext>());
return new AppRoleManager(roleStore);
}
}
}
using ITKA.Data.Entities;
//or just use ITKA.Data.Entities.Company
namespace ITKA.Domain.Classes
{
public class AppUser : IdentityUser
{
....
public virtual Company Company { get; set; }
....
}
}
using ITKA.Domain.Classes;
//or just use ITKA.Domain.Classes.AppUser;
namespace ITKA.Web
{
public class AppUserManager : UserManager<AppUser>
{
....
public virtual Company Company { get; set; }
....
}
}
现在是Web层——由于第1点,Web引用域层,允许它访问AppUser
类
IdentityConfig.cs
using System;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using Microsoft.AspNet.Identity.Owin;
using Microsoft.Owin;
using Microsoft.Owin.Security;
using ITKA.Domain.Classes;
using ITKA.Domain.Interfaces;
namespace ITKA.Web
{
public class AppUserManager : UserManager<AppUser>
{
public AppUserManager(IUserStore<AppUser> userStore)
: base(userStore)
{
}
public static AppUserManager Create(IdentityFactoryOptions<AppUserManager> options, IOwinContext context)
{
var userStore = new UserStore<AppUser>((IdentityDbContext<AppUser>)context.Get<IITKAContext>());
var manager = new AppUserManager(userStore);
manager.UserValidator = new UserValidator<AppUser>(manager)
{
AllowOnlyAlphanumericUserNames = false,
RequireUniqueEmail = true
};
manager.PasswordValidator = new PasswordValidator
{
RequiredLength = 8,
RequireNonLetterOrDigit = false,
RequireDigit = true,
RequireLowercase = true,
RequireUppercase = true
};
manager.UserLockoutEnabledByDefault = false;
manager.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5);
manager.MaxFailedAccessAttemptsBeforeLockout = 5;
return manager;
}
}
public class AppSignInManager : SignInManager<AppUser, string>
{
public AppSignInManager(AppUserManager userManager,
IAuthenticationManager authManager)
: base(userManager, authManager) { }
public static AppSignInManager Create
(IdentityFactoryOptions<AppSignInManager> options, IOwinContext context)
{
return new AppSignInManager(context.Get<AppUserManager>(),
context.Authentication);
}
}
public class AppRoleManager : RoleManager<IdentityRole>
{
public AppRoleManager(RoleStore<IdentityRole> roleStore)
: base(roleStore) { }
public static AppRoleManager Create(IOwinContext context)
{
var roleStore = new RoleStore<IdentityRole>
((IdentityDbContext<AppUser>)context.Get<IITKAContext>());
return new AppRoleManager(roleStore);
}
}
}
using ITKA.Data.Entities;
//or just use ITKA.Data.Entities.Company
namespace ITKA.Domain.Classes
{
public class AppUser : IdentityUser
{
....
public virtual Company Company { get; set; }
....
}
}
using ITKA.Domain.Classes;
//or just use ITKA.Domain.Classes.AppUser;
namespace ITKA.Web
{
public class AppUserManager : UserManager<AppUser>
{
....
public virtual Company Company { get; set; }
....
}
}
使用ITKA.Domain.Classes;
//或者只使用ITKA.Domain.Classes.AppUser;
名称空间ITKA.Web
{
公共类AppUserManager:UserManager
{
....
公共虚拟公司公司{get;set;}
....
}
}
您还必须在域层中保留IdentityDbContext,并在数据层中保留实体DbContext。不过,两者仍然可以指向相同的连接字符串
我希望这能有所帮助。谢谢你的回答。我想我明白你的意思,但我不明白我应该如何通过代码中的域层引用我的appuser。现在数据层需要引用域层,因为我的域层中有一个接口供上下文使用,所以我可以在我的identityconfig中“访问”上下文。另一件事是,我希望将标识表和实体表保持在同一个数据库中,我解决这个问题的方法是让我的dbcontext从identitydbcontext继承。“我将在下一个项目中探讨如何解决这个问题。”Robban-Ive更新了我的答案。让我知道这是否有用。是的,我现在更清楚了,谢谢。我在当前项目中实施此解决方案时会遇到问题,因为我从一开始就没有正确思考。在我的域层中有我的数据层使用的东西等等。但从现在起我肯定会考虑这个问题。也许正如您所说的,将域和服务层结合起来。回答得真好!很高兴我能帮忙。