2015-10-16 56 views
0

我們對此項目的數據庫使用實體框架代碼優先。最佳代碼中心ID表第一種方法

我們的需求需要一箇中心的'資源'表,帶有一列ResourceId(uniqueidentifier NOT NULL DEFAULT(newsequentialid()))。 各種表格將使用此表作爲其ID。

簡介 - 簡檔(唯一標識符NOT NULL) 組織 - OrganizationId(唯一標識符NOT NULL) 文件= DocumentId(唯一標識符NOT NULL)

所以,如果我創建一個新的檔案記錄,我將創建一個新的資源記錄並使用該順序創建的Guid作爲新配置文件記錄的ID。

原因是爲了防止配置文件中的Id始終作爲組織的Id存在。 (我知道,這是最有可能不可能的,但並非不可能。)

現在我們有關係,定義這個是這樣的:

public class Resource : BaseEntity 
{ 
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
    public Guid ResourceId { get; set; } 
    public virtual Profile Profile_ProfileId { get; set; } 
    //... 
} 

public class Profile : BaseEntity, IAuditableEntity 
{ 
    [Key]  
    public Guid ProfileId { get; set; } 
    public virtual Resource Resource { get; set; } 
    //... 
} 

public class ProfileMapping : EntityTypeConfiguration<Profile> 
{ 
    public ProfileMapping() 
    { 
     //Primary key 
     HasKey(t => t.ProfileId); 

     //Constraints 
     Property(t => t.ProfileId).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None); 
     //... 

     ToTable("Profile"); 

     //Create Relation 
     HasRequired(t => t.Resource).WithOptional(t => t.Profile_ProfileId); 
    } 
} 

然後,當我們創建一個新的配置文件,我們這樣做(DB是我們的DbContext的實例):

var res = new Resource(); 
db.Resource.Add(res); 

var newProfile = new Profile{ 
    ProfileId = res.ResourceId, 
    IsActive = true 
}; 

db.Profile.Add(newProfile); 

不過,我想,我們可以定義我們的類/型號可供資源繼承和獲得更好的效果?
有沒有人用過這樣的數據庫結構?

+0

如果這只是爲了防止重複的主鍵值這是一個**絕對沒用**矯枉過正。 GUID是[非常](http://stackoverflow.com/q/184869/861716)[不太可能](http://stackoverflow.com/q/3138395/861716)被複制。這將是一個沒有任何*好處的持續負擔。 –

+0

也許是這樣,不是我的電話。 :( –

回答

1

實際上,因爲ProfileIdOrganizationId的GUID是在同一臺數據庫服務器上生成的,所以您100%保證它們是唯一的。我假設你會讓數據庫服務器生成GUID。

如果GUID在不同的機器上生成,它們可能會碰撞(很小的機會)。

不管怎麼說,這是一個直接回答你的問題:

你可以做這樣的事情:

public class Resource 
{ 
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
    public Guid ResourceId { get; set; }   
} 

public class Profile 
{ 
    [Key] 
    [ForeignKey("Resource")] 
    public Guid ProfileId { get; set; } 

    public Resource Resource { get; set; } 

    public string Name { get; set; } 

    public Profile() 
    { 
     Resource = new Resource(); 
    } 
} 

注意Profile實體是如何創造它的構造一個Resource實體。另請注意,Profile的主鍵也是一個外鍵。

UPDATE:

這裏是另一種解決辦法,我認爲是更好的,這也將工作的情況下,你想從Resource實體訪問Profile實體:

我加了一個Profile財產的Resource實體:

public class Resource 
{ 
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
    public Guid ResourceId { get; set; } 

    public virtual Profile Profile { get; set; } 
} 

下面是簡介實體:

public class Profile 
{ 
    [Key, ForeignKey("Resource"), DatabaseGenerated(DatabaseGeneratedOption.None)] 
    public Guid ProfileId { get; set; } 

    public Resource Resource { get; set; } 

    public string Name { get; set; } 
} 

請注意,我不再在構造函數中創建一個Resource對象。

相反,我創造它時的實體是通過覆蓋在DbContext這樣的SaveChanges方法保存:

public class MyContext : DbContext 
{ 
    public DbSet<Resource> Resources { get; set; } 
    public DbSet<Profile> Profiles { get; set; } 

    public override int SaveChanges() 
    { 

     foreach (var profile in ChangeTracker.Entries<Profile>() 
      .Where(x => x.State == EntityState.Added)) 
     { 
      profile.Entity.Resource = new Resource(); 
     } 

     //Here you also need to do the same thing for other Entities that need a row in the Resources table (e.g. Organizations) 

     return base.SaveChanges(); 
    } 
} 
+0

那麼,那麼,我不需要在我的其他代碼中處理創建資源?我知道必須有一種方法 –

+0

是的,因爲每個'Profile'實例都會創建一個'Resource'對象 –

+0

一個後續問題如果我們想要從資源導航到代碼中的配置文件,例如:thisResource.Profile.Name;在這種情況下實現這個目的的最佳方式是什麼? –

相關問題