使用 ASP.NET 的 Identity2 與 EntityFramework 創(chuàng)建用戶體系

本文寫于2016年10月31日,因為只是在學習過程中的一些記錄,當時覺得公開發(fā)布的話可能還不太完善,于是只放到了 blogspot 上,現(xiàn)在發(fā)現(xiàn) Google 基本已經(jīng)不管 blogspot 了,也不會支持 Markdown,于是還是搬到簡書上來吧。


使用項目樣例

創(chuàng)建空項目并安裝樣例

首先可以創(chuàng)建一個空項目,然后使用Nuget命令行
Install-Package Microsoft.AspNet.Identity.Samples -Pre
將項目轉(zhuǎn)換為相關樣例,官方網(wǎng)址為:
https://www.nuget.org/packages/Microsoft.AspNet.Identity.Samples

修改數(shù)據(jù)庫連接

樣例的數(shù)據(jù)庫使用了自帶的 LocalDB,如果有 SQL Server 的環(huán)境,可以在 Web.config 中創(chuàng)建一個相關連接,然后在 IdentityModels.cs 文件中將連接改為相應的連接名。

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

上面使用官方樣例在 VS2015 下會不成功,不知道是否與環(huán)境有關,如果這樣的話,直接創(chuàng)建一個帶個人驗證的項目也是可以的,基本的用戶體系功能也會有。

創(chuàng)建默認用戶數(shù)據(jù)庫與已存在數(shù)據(jù)一對一的關系

修改數(shù)據(jù)庫屬性

假設已經(jīng)存在名字為 Staff 的數(shù)據(jù)庫表,Identity 模塊自動創(chuàng)建的用戶表為 AspNetUsers,為了將兩個表創(chuàng)建一對一的關系,需要對數(shù)據(jù)進行修改,為了避免系統(tǒng)創(chuàng)建的 AspNetUsers 表因為修改而產(chǎn)生未知的錯誤,決定修改 Staff 表。

而關于在 SQL Server 中創(chuàng)建表關系在 StackOverflow上有這么一個回答表述得很好:

Any relationship requires that the "parent" table (the one side) have a Primary (or unique) Key (PK), that uniquely identifies each row, and the "child" table (the other side) have a Foreign Key column or columns, that must be populated with values that are the same as some existing value[s] of the Primary Key in the parent table. If you want a one to many (1-M) relationship then the Foreign Key should be an ordinary attribute (column or columns) in the child table that can repeat (there can be many rows with the same value)

If you want a one to one (1-1) relationship then the Foreign key should itself be a Primary Key or unique index in the child table that guarantees that there may be at most one row in the child table with that value.

A 1-1 relationship effectively partitions the attributes (columns) in a table into two tables. This is called vertical segmentation. This is often done for sub-classing the table entities, or, for another reason, if the usage patterns on the columns in the table indicate that a few of the columns need to be accessed significantly more often than the rest of the columns. (Say one or two columns will be accessed 1000s of times per second and the other 40 columns will be accessed only once a month). Partitioning the table in this way in effect will optimize the storage pattern for those two different queries.

Sub-Classing. The above actually creates a 1 to zero or one relationship, which is used for what is called a sub-class or subtype relationship. This occurs when you have two different entities that share a great number of attributes, but one of the entities has additional attributes that the other does not need. A good example might be Employees, and SalariedEmployees. The Employee table would have all the attributes that all employees share, and the SalariedEmployee table would exist in a (1-0/1) relationship with Employees, with the additional attributes (Salary, AnnualVacation, etc.) that only Salaried employees need.

If you really want a 1-1 relationship, then you have to add another mechanism to guarantee that the child table will always have one record for each record/row in the parent table. Generally the only way to do this is by enforcing this in the code used to insert data (either in a trigger, stored procedure or code outside the database). This is because if you added referential integrity constraints on two tables that require that rows always be in both, it would not be possible to add a row to either one without violating one of the constraints, and you can't add a row to both tables at the same time.

參見 http://stackoverflow.com/questions/5112473/designing-11-and-1m-relationships-in-sql-server
另外還有一篇文章舉了不錯的例子 http://www.tech-recipes.com/rx/56738/one-to-one-one-to-many-table-relationships-in-sql-server/

上面說了,我們準備在 Staff 表中進行一定的修改,首先創(chuàng)建一個字段用于作為 AspNetUsers 的外鍵: aspNetUserId,注意類型需要與要關聯(lián)的另一個表的字段,即 Id 要相同,然后將這個字段設置為唯一的索引屬性,但是你會發(fā)現(xiàn)這個設置并不能成功,因為唯一的屬性需要這個字段上的值是不同的,而觀察這個字段屬性,發(fā)現(xiàn)勾選了允許為 null,但是如果去掉的話,顯然不能成功,因為這個字段是新加入的列,上面是不能有值的,當然,你可以用Excel生成一個等差序列先將這個空白填上。

填充關聯(lián)數(shù)據(jù)

剛才填充數(shù)據(jù)的那個操作只完成了一小半的工作,由于我們的最終目的是要關聯(lián)兩個表,因此我們需要真實的數(shù)據(jù)來進行表的數(shù)據(jù)是最科學,也是必須的。

由于 Identity2 默認的程序里已經(jīng)自帶了創(chuàng)建用戶的功能,因此我們改造下程序,使用 Staff 表中的登錄賬號生成 AspNetUsers 的相關賬號信息,然后將 AspNetUsersId 值同時保存至 Staff 新建字段 aspNetUserId 中即可(這里程序就不說了,很簡單,看看代碼就應該知道如何操作了)。

建立兩個表的一對一關系

數(shù)據(jù)已經(jīng)填充好,現(xiàn)在重復之前說的,將 Staff 中的字段 aspNetUserId 設置為唯一索引屬性,然后在 Staff 創(chuàng)建關系,相關聯(lián)的字段當然是 aspNetUserIdAspNetUsersId 字段,保存后即可看到兩個表上出現(xiàn)了一對一的連接關系。

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容