はい、
public ICollection<IncomeType> IncomeTypes { get; set; } = new List<IncomeType>();
のようなコードは、ASP.NET Core MVC + Entity Framework Core で 1対多 (One-to-Many) または多対多 (Many-to-Many) のリレーションをモデルに定義する場合に必要です。
1. このコードが必要なケース
- 親エンティティが複数の子エンティティを持つ場合
- 例:
IncomeCategory が複数の IncomeType を持つ
- ナビゲーションプロパティを使って関連データを取得・保存したい場合
- EF Core の遅延読み込み / 明示的読み込み / 即時読み込みで関連データを扱う場合
- 新規作成時にコレクションを初期化して NullReferenceException を防ぎたい場合
2. 完全なモデルとリレーション設定例
モデル定義
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace MyApp.Models
{
// 親モデル: 収入カテゴリ
public class IncomeCategory
{
public int Id { get; set; }
[Required]
[StringLength(100)]
public string Name { get; set; }
// 1対多: IncomeCategory → IncomeType
public ICollection<IncomeType> IncomeTypes { get; set; } = new List<IncomeType>();
}
// 子モデル: 収入タイプ
public class IncomeType
{
public int Id { get; set; }
[Required]
[StringLength(100)]
public string TypeName { get; set; }
// 外部キー
public int IncomeCategoryId { get; set; }
// ナビゲーションプロパティ
public IncomeCategory IncomeCategory { get; set; }
}
}
DbContext 設定
using Microsoft.EntityFrameworkCore;
using MyApp.Models;
namespace MyApp.Data
{
public class ApplicationDbContext : DbContext
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options) { }
public DbSet<IncomeCategory> IncomeCategories { get; set; }
public DbSet<IncomeType> IncomeTypes { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
// 1対多のリレーション設定
modelBuilder.Entity<IncomeCategory>()
.HasMany(c => c.IncomeTypes)
.WithOne(t => t.IncomeCategory)
.HasForeignKey(t => t.IncomeCategoryId)
.OnDelete(DeleteBehavior.Cascade);
}
}
}
マイグレーションとDB作成
dotnet ef migrations add InitialCreate
dotnet ef database update
コントローラー例(関連データの取得)
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using MyApp.Data;
namespace MyApp.Controllers
{
public class IncomeCategoriesController : Controller
{
private readonly ApplicationDbContext _context;
public IncomeCategoriesController(ApplicationDbContext context)
{
_context = context;
}
public async Task<IActionResult> Index()
{
// Includeで関連データを同時取得
var categories = await _context.IncomeCategories
.Include(c => c.IncomeTypes)
.ToListAsync();
return View(categories);
}
}
}
ポイント
ICollection<IncomeType> は、EF Core がリレーションを認識し、関連データを格納するためのナビゲーションプロパティ。= new List<IncomeType>() により、インスタンス生成時にコレクションが初期化され、NullReferenceException を防ぐ。HasMany / WithOne で明示的にリレーションを設定すると、外部キーや削除動作を制御できる。
もし希望があれば、このモデルを使った Create/Edit ビューで IncomeType を同時に登録するフォーム例 も作れますが、
それも含めて作りますか?
そうすれば、IncomeTypes を持つケースがより実践的に理解できます。
Powered by Froala Editor