Sni*_*fer 2 entity-framework-4 asp.net-mvc-3
好的 - 先道歉 - 我是一个前端开发人员(HTML,CSS和JS)试图用数据做事 - 从来都不错!
我有一个'Page',可以有一个或多个'系列'.这些"系列"可以包含一个或多个"收藏",这些"收藏"可以与多个"系列"相关联.'Collection'可以包含一个或多个'标题'.这就是我构建数据库的方式:
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])
Run Code Online (Sandbox Code Playgroud)
使用实体框架我有以下内容:
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; }
Run Code Online (Sandbox Code Playgroud)
在视图中我想得到以下内容.
对于给定的'Page'(id),我想要所有'Series'并且在每个'Series'中,能够列出每个'标题'及其相关的'Collection'.
首先 - 我的数据库设置正确吗?其次,我正在努力使用db调用和viewmodels来返回它.
如果有人能帮助那就好了
提前致谢
'Collection'可以包含一个或多个'标题'.
因此,我会修改您的数据库表架构:
在表Titles代替[SeriesCollectionId]由[CollectionId]直接指的对Collections表.
在表中SeriesCollections删除您的PK [SeriesCollectionId]并改为使用剩余的两个字段[SeriesId]和[CollectionId]复合主键.
现在,你可以模型之间的许多一对多的关系Series,并Collections与EF.然后,连接表SeriesCollections不再是模型的一部分.它只是数据库中隐藏的表,由EF管理.因此你可以删除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; }
}
Run Code Online (Sandbox Code Playgroud)
对于多对多映射,您需要Fluent 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");
});
}
}
Run Code Online (Sandbox Code Playgroud)
我相信EF会按惯例找出所有其他关系.
对于给定的'Page'(id),我想要所有'Series'并且在每个'Series'中,能够列出每个'标题'及其相关的'Collection'.
使用上面的模型,您可以尝试:
var page = context.Pages.Where(p => p.PageId == id)
.Include(p => p.Series.Select(s => s.Collections.Select(c => c.Titles)))
.SingleOrDefault();
Run Code Online (Sandbox Code Playgroud)
它将选择包含系列列表的页面,其中包含带有标题列表的集合列表.
不确定这是不是你想要的,只是一个未经测试的起点.
(顺便说一下:你可以先编写你的类(Code-First),然后让EF创建你的数据库表.在设计阶段你想尝试一些映射时更容易,imo.)
编辑
我忘了一件事:如果你真的想要非变量固定长度的字符串字段(NCHAR(50)),你必须在Fluent API中明确地定义它.默认情况下,EF会假设NVARCHAR(50)上面带有映射的字段.设置为固定长度列将如下所示:
modelBuilder.Entity<Page>().Property(p => p.Title).IsFixedLength();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2142 次 |
| 最近记录: |