joh*_* Gu 7 asp.net asp.net-mvc asp.net-mvc-5 asp.net-identity asp.net-identity-2
我有以下内容: -
aspnet-OurProjectNanme-numberAspNetUSers存储用户信息的表.现在我正在建立一个ERP系统.在ERP系统内部,我想添加以下内容: -
CreatedBy"+" ModifiedBy",它应存储创建和修改资产项的userId.现在我不确定我需要如何实现这一目标?因为我需要在我的自定义表"Asset"和自动创建的"AspNetUsers"表之间添加一个外键.. 所以我可以在自动生成的数据库中添加我的自定义表"Asset",并在之间构建外键在Asset.CreatedBy和AspNetUsers.Id?
如果答案是肯定的,那么如果我们想要升级我们的aspnet身份版本,这种关系将来会破裂吗?因为升级身份可能会导致创建新表或重命名现有表等.这可能会破坏Asset表和AspNetUsers表之间的关系?
如果答案是否(我不应该在自动生成的数据库中添加自定义表)那么我如何构建外键?在这种情况下我需要添加资产表?
小智 4
- 更新 -
答案越来越多,讨论也越来越多。我想我已经展示了各种变化,这可能无助于理解它。所以这里是一个总结。如需解释,请阅读完整答案和讨论。
开箱即用,您有两个上下文:身份和业务。它们是分离的,因此您可以在不影响业务的情况下更改安全性。这样,升级安全性就不会破坏您的应用程序或其他模型。由于上下文是独立的,因此对其中一个的更改不会影响另一个。
旁注:您不打算直接访问 AspNet 身份表。实现 UserManager 并使用管理器的可用方法来执行操作。
现在说到逻辑,信息应该存储在哪里?作为一个简单的规则,只需问自己一个问题:它是安全的一部分还是业务的一部分?
在这两种情况下你都有用户。对于您的要求,这是逻辑上的 1:1 关系。但它们实际上是分开的。您可以在不提供登录名的情况下创建人员,也可以删除登录名,而无需删除用户(人员),例如由于历史原因。
您想要的只是查找当前用户的所有信息。所以您所需要的只是 People.Id。
无需更改 IdentityUser,您只需覆盖 AspNetUser.Id 即可创建 1:1 关系。
var appUser = new IdentityUser
{
UserName = model.Email,
Email = model.Email,
Id = Convert.ToString(People.Id)
};
var identityResult = await userManager.CreateAsync(appUser, model.Password);
Run Code Online (Sandbox Code Playgroud)
您的业务不需要身份上下文。您所需要的只是 People.Id。身份上下文仅在颁发令牌和创建/修改用户时使用。
要获取 id,请使用类似以下内容:
var peopleId = int.Parse(Request.User.Identity.GetUserId());
Run Code Online (Sandbox Code Playgroud)
现在您可以使用 Id 查询您的业务模型。
注册时,使用要存储的人员信息扩展 View 和 ViewModel。这将允许您同时添加 People 和 AspNetUser。尽管这不是一笔交易。但我认为,如果您首先执行检查,创建任何一个都不太可能失败。
您可以在创建用户之前验证用户名和密码(使用 UserManager 中的方法)并检查视图模型的 ModelState。使用属性强制填写必填字段。
——原答案——
为了不重复自己,请阅读我的答案。
简而言之,将身份和业务分开。以防万一从同一个数据库中删除身份逻辑,就像实现 IdentityServer 时一样。
看来您在 AspNetUser 中有商业信息。如果是这样,请创建一个“人员”表并将信息移至该表。与模型中的该表相关。在表 Person 中,您可以添加对 AspNetUser 的引用。
- 更新 -
我认为您理解正确,但我只会在这个答案中添加详细信息。
在大多数情况下,所有表都在一个数据库中定义。但这并不意味着它们都是同一模型的一部分。可以有多个上下文。在这种情况下,一个用于身份,一个(或多个)用于业务。
现在为什么要把这两个分开呢?业务模型和身份模型之间最重要的区别是身份表不能直接调用。我们使用 Owin 上下文来调用 UserManager / RoleManager。
这就是为什么我们不能将这些表添加到业务模型中。事情可能会以不安全的方式改变。我们也不希望企业了解任何有关授权的知识。只要用户被识别并获得授权,如何完成并不重要。
此外,您可能希望实现 OpenId 和基于声明的授权。在这种情况下,信息不必在数据库中可用。
这个想法是创建身份表 AspNetUsers 和业务表 People 的 1:1 关系。可能存在一些冗余,例如电子邮件或(用户)名。但这不是问题。People 表应包含您想要在业务模型中使用的所有信息。并且业务表应该只与人员相关,而不是与 AspNetUsers 相关。
现在介绍 AspNetUsers 和 People 之间的链接。有四种选择:
设置 People.Id = AspNetUser.Id。请注意,AspNetUser.Id 不必是 GUID。您可以添加自己的值作为键。
设置 AspNetUser.Id = People.Id。
将列 AspNetUserId 添加到 People。无需对身份进行任何修改。您也可以将人员添加到身份模型中,但我认为您不能在一项事务中创建这两个记录。您可以使用 User.Identity.GetId() 来获取 AspNetUser.Id。然而,您可能会问自己,企业是否应该了解这些信息。
将列 PeopleId 添加到 AspNetUsers。您需要扩展 IdentityUser 以添加 PeopleId。一个优点是您不需要 AspNetUser Id,但您可以使用 People 的实际 Id。使用 OpenId 或声明时,您可以从声明中获取 People.Id,并且无需将 AspNetUser.Id 添加到业务中。您可以选择将 People 添加到模型中并作为扩展 IdentityUser 的导航属性。创建用户时,您可以在一次事务中完成此操作。
如果您在单独的上下文中创建用户,则需要自己处理回滚。但在向 People 添加记录之前,您已经可以测试是否可以添加 AspNetUser:具有有效的名称/电子邮件和密码。
由于您的业务模型与 People 表相关,因此您可以查询所有资产并连接 People 表以获取更多信息。或者您可以获取当前用户的所有资产。
o 是的,有两个上下文。身份模型,其中包含 AspNet...表 + 可选的人员。以及业务模型,其中包含所有 ERP 表 + 资产 + 人员。
您可以考虑对身份框架 2 使用代码优先,对业务模型使用数据库优先。
我希望这个对你有用。如果没有,我们继续聊天。
- 更新 -
答案集中在领域的分离:身份和业务。这就是为什么我没有讨论有关 AspNetUsers 表的一种可能的替代方案。
这两个模型是数据库的表示,这意味着数据库不必完全匹配。您可以随意映射表和字段,只要它们不破坏数据库逻辑即可。
由于 AspNetusers 和 People 具有 1:1 关系,当两个表都存在于同一数据库中时,您也可以将两个表合并到 AspNetUsers 表中。您还可以向 AspNetUsers 表添加关系,但您可能希望添加额外的 Id (int) 列而不是使用当前的 Id(字符串)。
这并不意味着 People 类可以被丢弃,只是我们必须更改表映射:AspNetUsers。
例子:
[Table("AspNetUsers")]
public class People
{
[Required]
[StringLength(128)]
public string Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
如您所见,敏感字段未映射。然而我们需要 Id 字段。您现在可以读取和更新映射的字段。
您不必扩展 IdentityUser。您可以添加 AspNetUser,然后使用其他上下文中的 People 更新字段。但是,如果您想在单个事务中添加用户,扩展 IdentityUser 可能会更容易(确保您在 People 和 ApplicationUser 中定义新字段):
public class ApplicationUser : IdentityUser
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
有多个优点:
请注意,这可能不适用于所有类型的模型(代码优先/数据库优先+迁移)。
| 归档时间: |
|
| 查看次数: |
1805 次 |
| 最近记录: |