2011-08-23 78 views
2

好的 - 首先道歉 - 我是一個嘗試使用數據做事的前端開發人員(HTML,CSS和JS) - 從來不漂亮!實體框架,MVC 3,一對多關係

我有一個'頁面',可以有一個或多個'系列'。這些「系列」可以包含一個或多個「集合」,這些「集合」可以與多個「系列」相關聯。 '收藏'可以擁有一個或多個'標題'。這是我是如何構建我的分貝:

CREATE TABLE [dbo].[Pages] (
    PageId INT  NOT NULL PRIMARY KEY, 
    [Title] NCHAR(50) NOT NULL 
) 

CREATE TABLE [dbo].[Series] (
    [SeriesId] INT  NOT NULL, 
    [Title] NCHAR (50) NOT NULL, 
    [PageId] INT  NOT NULL, 
    PRIMARY KEY CLUSTERED ([SeriesId] ASC), 
    CONSTRAINT [FK_Series_Pages] FOREIGN KEY ([PageId]) REFERENCES [Pages]([PageId]) 
); 

CREATE TABLE [dbo].[Collections] (
    [CollectionId] INT  NOT NULL, 
    [Title]  NCHAR (50) NOT NULL, 
    PRIMARY KEY CLUSTERED ([CollectionId] ASC) 
); 

CREATE TABLE [dbo].[SeriesCollections] (
    [SeriesCollectionId] INT NOT NULL, 
    [SeriesId]    INT NOT NULL, 
    [CollectionId]   INT NOT NULL, 
    PRIMARY KEY CLUSTERED ([SeriesCollectionId] ASC), 
    CONSTRAINT [FK_SeriesCollections_Series] FOREIGN KEY ([SeriesId]) REFERENCES [Series]([SeriesId]), 
    CONSTRAINT [FK_SeriesCollections_Collections] FOREIGN KEY ([CollectionId]) REFERENCES [Collections]([CollectionId]) 
); 

CREATE TABLE [dbo].[Titles] (
    [TitleId]   INT   NOT NULL, 
    [Title]    NCHAR (100) NOT NULL, 
    [SeriesCollectionId] INT   NOT NULL, 
    PRIMARY KEY CLUSTERED ([TitleId] ASC), 
    CONSTRAINT [FK_Titles_SeriesCollections] FOREIGN KEY ([SeriesCollectionId]) REFERENCES [SeriesCollections]([SeriesCollectionId]) 

使用實體框架我有以下幾點:

public DbSet<Page> Pages { get; set; } 
public DbSet<Series> Series { get; set; } 
public DbSet<Collection> Collections { get; set; } 
public DbSet<SeriesCollection> SeriesCollections { get; set; } 
public DbSet<Title> Titles { get; set; } 

在我想要得到以下的看法。

對於給定的'頁面'(id),我想要所有'系列',並在這些'系列'的每一箇中,能夠列出每個'標題'及其關聯的'收藏'。

首先 - 我的db設置正確嗎?其次,我正在努力與db調用和viewmodels將返回此。

如果有人能幫助那簡直太好了

在此先感謝

回答

5

的「收藏的可以容納一個或多個‘頭銜’。

因爲這樣我會修改你的數據庫表的模式:

  • 在表Titles通過[CollectionId]更換[SeriesCollectionId],直接闖民宅到Collections表。

  • 在表SeriesCollections刪除您的PK [SeriesCollectionId]並代替其餘兩個字段[SeriesId][CollectionId]到一個複合主鍵。

  • 現在,您可以建立SeriesCollections與EF之間的多對多關係。然後,連接表SeriesCollections不再是您的模型的一部分。這只是EF管理的DB中的一個隱藏表。因此您可以刪除public DbSet<SeriesCollection> SeriesCollections { get; set; }。然後

模型類看起來是這樣的:

public class Page 
{ 
    public int PageId { get; set; } 
    [Required] 
    [MaxLength(50)] 
    pubic string Title { get; set; } 
    public ICollection<Series> Series { get; set; } 
} 

public class Series 
{ 
    public int SeriesId { get; set; } 
    [Required] 
    [MaxLength(50)] 
    pubic string Title { get; set; } 
    public int SeriesId { get; set; } 
    public int PageId { get; set; } // FK property, helpful but not required 
    public Page Page { get; set; } 
    public ICollection<Collection> Collections { get; set; } 
} 

public class Collection 
{ 
    public int CollectionId { get; set; } 
    [Required] 
    [MaxLength(50)] 
    pubic string Title { get; set; } 
    public ICollection<Series> Series { get; set; } 
    public ICollection<Title> Titles { get; set; } 
} 

public class Title 
{ 
    public int TitleId { get; set; } 
    [Required] 
    [MaxLength(100)] 
    pubic string TTitle { get; set; } // must be other name then class 
    public int CollectionId { get; set; } // FK property 
    public Collection Collection { get; set; } 
} 

對於許多一對多映射需要流利的API:

public class MyContext : DbContext 
{ 
    public DbSet<Page> Pages { get; set; } 
    public DbSet<Series> Series { get; set; } 
    public DbSet<Collection> Collections { get; set; } 
    public DbSet<Title> Titles { get; set; } 

    protected override void OnModelCreating(DbModelBuilder modelBuilder) 
    { 
     modelBuilder.Entity<Series>() 
      .HasMany(s => s.Collections) 
      .WithMany(c => c.Series) 
      .Map(a => 
      { 
       a.MapLeftKey("SeriesId"); 
       a.MapRightKey("CollectionId"); 
       a.ToTable("SeriesCollections"); 
      }); 
    } 
} 

EF會找出所有其他關係約定,我相信。

對於給定的「頁面」(ID),我希望所有的「系列」,並在每個 那些「系列」,可以列出每個「標題」及其 相關的「集」的。

有了那麼你上面的模型可以嘗試:

var page = context.Pages.Where(p => p.PageId == id) 
    .Include(p => p.Series.Select(s => s.Collections.Select(c => c.Titles))) 
    .SingleOrDefault(); 

這將選擇包含一系列具有收藏與標題的列表清單列表頁。

不知道這是否正是你想要的,只是一個未經測試的起點。

(順便說一句:你可以先寫你的類(代碼優先),並讓EF創建數據庫表,當你想嘗試一些映射這是在設計階段更容易,海事組織。)

編輯

我忘了一件事:如果你真的想要非變量固定長度的字符串字段(NCHAR(50)),你必須在Fluent API中明確地定義它。默認情況下,EF會假設帶有上面映射的NVARCHAR(50)字段。設置爲固定長度的列將如下所示:

modelBuilder.Entity<Page>().Property(p => p.Title).IsFixedLength(); 
+0

這很棒,並教會了我加載,以及給我更多的東西去了解和了解!愛上Fluent API。感謝您花時間查看我的問題 - 非常感謝。 – Sniffer