Коллекция может содержать одно или несколько «Титулов».
Из-за этого я бы изменил схему таблицы вашей БД:
В таблице 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; }
}
Для сопоставления «многие ко многим» вам необходим 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");
});
}
}
EF выяснит все остальные отношения по соглашению, я считаю.
Для данной «Страницы» (id) я хочу все «Серии» и внутри каждого из
те «серии», быть в состоянии перечислить каждое из «Титулов» и его
связанная «Коллекция».
С моделью выше вы можете попробовать:
var page = context.Pages.Where(p => p.PageId == id)
.Include(p => p.Series.Select(s => s.Collections.Select(c => c.Titles)))
.SingleOrDefault();
Будет выбрана страница, содержащая список серий со списком коллекций со списком заголовков.
Не уверен, что это именно то, что вам нужно, просто непроверенная отправная точка.
(Кстати: вы можете сначала написать свои классы (Code-First) и позволить EF создавать таблицы базы данных. На этапе проектирования проще, когда вы хотите попробовать некоторые отображения, imo.)
Редактировать
Одна вещь, которую я забыл: если вы действительно хотите нефиксированные строковые поля фиксированной длины (NCHAR(50)
), вы должны явно указать это в Fluent API. По умолчанию EF будет принимать NVARCHAR(50)
полей с отображением выше. Установка столбцов фиксированной длины будет выглядеть следующим образом:
modelBuilder.Entity<Page>().Property(p => p.Title).IsFixedLength();