2 回答

TA貢獻1796條經(jīng)驗 獲得超10個贊
即使我在沒有鍵和關(guān)系的另一個數(shù)據(jù)庫中創(chuàng)建表,我也無法重現(xiàn)該問題。所以我確定你的模型有問題。不幸的是,您沒有添加我可以比較的代碼,所以我無法說出有什么不同并直接回答問題。我唯一能做的就是展示什么對我有用。不過,首先我要說幾點。
我認為你不應(yīng)該關(guān)注這篇文章。因為沒有理由將上下文添加到現(xiàn)有數(shù)據(jù)庫中。
就像 Ivan Stoev 提到的,你不應(yīng)該混合上下文。身份上下文旨在對用戶進行身份驗證。它存儲憑據(jù)、用戶角色和聲明。其中聲明旨在添加有關(guān)用戶的身份信息。
實際上,Hometown
ApplicationUser 模板的默認字段可以刪除,因為它是一個身份聲明,應(yīng)該存儲在 AspNetUserClaims 表中。不是您需要擴展 ApplicationUser 的東西。實際上,我想不出任何擴展 ApplicationUser 的理由。
關(guān)于角色,這些并不是真正的聲明,因為它們沒有說明身份,而是用于授權(quán)。這就是為什么它們可以存儲在 AspNetUserRoles 表中的原因。不幸的是,角色作為角色聲明被添加到身份中,這讓事情變得混亂。
請注意,身份信息存在于聲明中。這意味著應(yīng)用程序不必調(diào)用身份上下文。例如 User.IsInRole 檢查當(dāng)前身份的角色聲明,而不是存儲在表中的角色。
關(guān)于不同的上下文,另一個上下文(我通常稱之為業(yè)務(wù)模型)與 Identity 上下文沒有任何共同之處。電子郵件和其他領(lǐng)域不是商業(yè)模式的一部分,也沒有意義。您可能認為這些字段是多余的,但實際上并非如此。我可以使用谷歌帳戶登錄,但對于業(yè)務(wù),請使用我的工作電子郵件地址。
將上下文分開有幾個原因。
關(guān)注點的分離。假設(shè)您將來要與另一個身份驗證框架交換身份驗證框架。如果您想支持單點登錄 (SSO),就像實施 IdentityServer 一樣。
如果另一個應(yīng)用程序需要相同的登錄名,則不能將用戶表移動到另一個數(shù)據(jù)庫。因此,您最終還要向數(shù)據(jù)庫添加其他上下文。
遷移問題。如果混合上下文,則遷移將失敗。
它會讓事情變得容易得多。這是您遇到的第一個問題,而不是最后一個。
正如文章中所提到的:
此時,如果您需要將任何關(guān)系(例如外鍵)從您自己的表添加到這些表,歡迎您這樣做,但不要直接或稍后在其任何 POCO 類上修改任何實體框架 2.0 表。根據(jù)我收到的反饋,這樣做會導(dǎo)致錯誤。
那么,如果您不應(yīng)該從您的應(yīng)用程序訪問身份上下文,那么如何管理信息呢?
對于當(dāng)前用戶,您不需要訪問 users 表。所有信息都存在于身份聲明中。訪問身份上下文的唯一原因是允許用戶登錄。除了用戶管理。
您可以通過添加對用戶的引用(用戶 ID)就足夠了。如果您需要在報告中顯示其他用戶的信息(如姓名),則在您的業(yè)務(wù)上下文中創(chuàng)建一個用戶表來存儲信息。您可以向該表添加關(guān)系,因為它是同一上下文的一部分。
如果您對此方法有任何疑問,請告訴我。
現(xiàn)在對我有用的代碼。就像其他人提到的那樣,不太可能添加以下行:
public ICollection<Employee> Employees { get; set; }
是原因。如果沒有virtual
關(guān)鍵字,我認為它甚至?xí)缓雎裕ū3譃榭眨?/p>
當(dāng)我按照文章的步驟進行操作時,我最終會得到以下模型:
public class ApplicationUser : IdentityUser
{
public string Hometown { get; set; }
//public virtual ICollection<Employee> Employees { get; set; }
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;
}
}
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
// Disable migrations
//Database.SetInitializer<ApplicationDbContext>(null);
}
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
}
然后我添加 Employee 類并取消注釋上面 ApplicationUser 類中的行:
public class Employee
{
public int Id { get; set; }
public string Name { get; set; }
//public virtual ApplicationUser ApplicationUser { get; set; }
public string ApplicationUserId { get; set; }
}
在數(shù)據(jù)庫中,我添加了表:
CREATE TABLE [dbo].[Employees](
[Id] [int] NOT NULL,
[Name] [varchar](50) NOT NULL,
[ApplicationUserId] [nvarchar](128) NOT NULL,
PRIMARY KEY CLUSTERED
(
[Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
您可以使用該[ForeignKey]屬性來使用不同的字段名稱。
您可以嘗試這樣做或選擇將兩個上下文分開。

TA貢獻1805條經(jīng)驗 獲得超10個贊
憂慮:
我確切地知道你在這里的負擔(dān)是什么。是的,微軟,一個深奧的邪教,在為這個與身份(實體框架)建立關(guān)系的問題提供信息方面做得很差。
貢獻:
Ruard van Elburg 于 8 月 24 日 16:31 發(fā)表的帖子對此事給出了很好的見解;但是,我注意到他的代碼中缺少一個關(guān)鍵組件,即需要放置在 IdentityModels 的 DBContext 中的 DbSet。
技術(shù)棧:
我提供了我的技術(shù)堆棧,以便如果這不適用于舊版本的軟件,您就會知道我用什么來解決這個問題。
Visual Studio 2017 MVC 5。僅供參考,MVC 5 內(nèi)置于最新的 VS 中。
SQL Server 17
MS SQL 管理工作室 17
解決方案:
免責(zé)聲明?。。∥抑朗紫汝P(guān)注的是數(shù)據(jù)庫;但是,此解決方案僅適用于代碼優(yōu)先方法。但是,嘿,它有效!
在這里,我提供了有關(guān)如何執(zhí)行此操作的演練。請確保您在代碼的上邊距中擁有所有依賴項。
步驟1:添加 public virtual DbSet<ModelNameOfInterest> ModelNameOfInterest { get; set; }
到public class ApplicationDbContext : IdentityDbContext<ApplicationUser>{}
如在下面看到的代碼。
using System.Data.Entity;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using System.ComponentModel.DataAnnotations.Schema;
namespace AwesomeCode.Models
{
// You can add profile data for the user by adding more properties to your ApplicationUser class, please visit http://go.microsoft.com/fwlink/?LinkID=317594 to learn more.
public 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;
}
}
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
}
//A virtul DbSet in order to interact with the autogenerated code the identity framewrok produces.
public virtual DbSet<ModelNameOfInterest> ModelNameOfInterest { get; set; }
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
}
}
第 2 步:添加public virtual ApplicationUser ApplicationUser { get; set; }到您要與之建立關(guān)系的模型中,如下所示。
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Web;
namespace AwesomeCode.Models
{
public class WorkExp
{
[Key]
public int Id { get; set; }
public string JobTitle { get; set; }
//Create foreign key with reference to ApplicationUser_Id that was auto-generated by entity framework.
public virtual ApplicationUser ApplicationUser { get; set; }
}
}
第 3 步:鑒于您為數(shù)據(jù)庫設(shè)置了連接字符串,您需要生成遷移。包管理器控制臺的路徑:工具->NuGet Packer Manager->包管理器控制臺
如果根目錄中不存在遷移文件夾,則啟用遷移:在
PM>
鍵入之后,Enable-Migrations
您應(yīng)該會看到一個包含兩個文件的遷移文件夾。啟用遷移后: After
PM>
,請鍵入Update-Database
You should see tables in your database now。添加另一個遷移: After
PM>
,鍵入Add-Migration
AfterName:
,鍵入InitialCreate
或Your model of interest
您現(xiàn)在應(yīng)該會在您的數(shù)據(jù)庫中看到表。您現(xiàn)在應(yīng)該可以看到數(shù)據(jù)庫中的表。
第 4 步:仔細檢查感興趣的模型的外鍵是否正確引用到 AspNetUser 表。在 MS Management Studio 中,您可以創(chuàng)建關(guān)系圖來顯示引用。你可以在谷歌上找到如何做到這一點。
第 5 步:一如既往地保持冷靜、冷靜和鎮(zhèn)定。
- 2 回答
- 0 關(guān)注
- 260 瀏覽
添加回答
舉報