2016-09-30 69 views
1

最近我一直在玩使用實體框架的SQLite,但有些關於在DB第一種方法後生成的實體的導航屬性並不是很清楚。更具體地說,是多對多的關係。使用SQLite和實體框架時錯誤的導航屬性6

注意:使用ASP.NET Web Api OWIN項目。

這是我做過什麼:

  1. 我安裝了最新版本的實體框架

  2. 我安裝了最新版本的System.Data.SQLite

  3. 我用Firefox插件來創建我的數據庫。它生成的我* .sqlite

示例,而創建DB我的許多一對多分貝的定義之一:

CREATE TABLE "Users" 
(
    "Id" INTEGER PRIMARY KEY NOT NULL UNIQUE , 
    "IdSrvId" INTEGER NOT NULL UNIQUE , 
    "FirstName" VARCHAR NOT NULL , 
    "LastName" VARCHAR NOT NULL , 
    "Email" VARCHAR NOT NULL , 
    "About" VARCHAR NOT NULL , 
    "GenderId" INTEGER NOT NULL UNIQUE , 
    "BirthDate" DATETIME, 
    "PhoneNumber" VARCHAR 
) 

CREATE TABLE "UserLanguаges" 
(
    "Id" INTEGER PRIMARY KEY NOT NULL UNIQUE , 
    "UserId" INTEGER NULL REFERENCES Users(Id), 
    "LanguageId" INTEGER NULL REFERENCES Languаges(Id) 
) 

CREATE TABLE "Langugaes" 
(
    "Id" INTEGER PRIMARY KEY NOT NULL UNIQUE , 
    "Name" VARCHAR NOT NULL UNIQUE 
) 

在那之後,我使用的Visual Studio 2015年創建使用該數據模型* .sqlite文件。下面這個教程:SQLite EntityFramework 6 Tutorial

我得到了我所有的表爲尋找這樣的實體生成後:

public partial class User 
{ 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")] 
    public User() 
    { 
     this.GroupUsers = new HashSet<GroupUser>(); 
     this.UserLanguаges = new HashSet<UserLanguаges>(); 
    } 

    public long Id { get; set; } 
    public long IdSrvId { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public string Email { get; set; } 
    public string About { get; set; } 
    public long GenderId { get; set; } 
    public Nullable<System.DateTime> BirthDate { get; set; } 
    public string PhoneNumber { get; set; } 

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] 
    public virtual ICollection<UserLanguаges> UserLanguаges { get; set; } 
} 

public partial class Languаges 
{ 
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")] 
    public Languаges() 
    { 
     this.UserLanguаges = new HashSet<UserLanguаges>(); 
    } 

    public long Id { get; set; } 
    public string Name { get; set; } 

    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")] 
    public virtual ICollection<UserLanguаges> UserLanguаges { get; set; } 
} 

public partial class UserLanguаges 
{ 
    public long Id { get; set; } 
    public Nullable<long> UserId { get; set; } 
    public Nullable<long> LanguageId { get; set; } 

    public virtual Languаges Languаges { get; set; } 
    public virtual User User { get; set; } 
} 

什麼在這裏我擔心,在裏面用戶語言實體導航屬性。正如你所看到的,他們提到了「橋樑」表,它幫助我們達成了多對多的關係,但並沒有像我預期的那樣直接向另一個實體提供幫助。

我預計:

public virtual ICollection<UserLanguаges> UserLanguаges { get; set; } 

看起來像這樣:

public virtual ICollection<Languаge> Languаges { get; set; } 

用戶實體內。

我該如何解決這個問題?

回答

1

Entity Framework可以省略連接表的唯一時間是該表是否僅包含以多對多關係連接的表的鍵。這是表中的Id列的存在,導致它產生一個新的實體。

解決此問題的唯一方法是刪除該Id列並使該表具有由UserId和LanguageId鍵組成的組合鍵。如果您無法更改數據庫模式,則沒有其他選擇,只需深呼吸並接受它的工作方式。

在EF如何處理許多一對多關係的一些額外閱讀:https://msdn.microsoft.com/en-us/library/dd742359.aspx

+0

所以,你說,如果「橋」表中沒有自己的ID字段,而是複合的ID(用戶ID, LanguageId)它會確保我在生成的實體中正確的導航屬性? – user2128702

+1

是的,確切地說。順便說一下,實體框架是如何在代碼優先的工作流程中創建表格的。 – PMV