Welcome to the C# development docs
Helpful .NET summaries and practical examples.
→ Official C# EntityFramework Documentation
public class Post
{
[Key]
public int Id { get; set; }
[Required]
[MinLength(5)]
[MaxLength(255)]
[Column(TypeName = "nvarchar(max)")]
[Index(nameof(Title), IsUnique = true)] -> For Emails: [UniqueEmail]
public string Title { get; set; } = string.Empty; { get; set; } = string.Empty;
[Required]
[DataType(DataType.MultilineText)]
public string Content { get; set; } = string.Empty;
[Required]
public string AuthorId { get; set; } = string.Empty;
[ForeignKey("AuthorId")]
public AppUser Author { get; set; } = null!;
public List Comments { get; set; } = new();
public List PostTags { get; set; } = new();
}
public class Tag
{
[Key]
public int Id { get; set; }
[Required]
[MinLength(2)]
[MaxLength(100)]
[Column(TypeName = "nvarchar(100)")]
public string Name { get; set; } = string.Empty; { get; set; } = string.Empty;
public List PostTags { get; set; } = new();
}
public class PostTag
{
[Key]
[Column(Order = 0)]
public int PostId { get; set; }
[ForeignKey("PostId")]
public Post Post { get; set; } = null!;
[Key]
[Column(Order = 1)]
public int TagId { get; set; }
[ForeignKey("TagId")]
public Tag Tag { get; set; } = null!;
}
public class Comment
{
[Key]
public int Id { get; set; }
[Required]
[MinLength(2)]
[MaxLength(500)]
[Column(TypeName = "nvarchar(500)")]
public string Text { get; set; } = string.Empty; { get; set; } = string.Empty;
[Required]
public int PostId { get; set; }
[ForeignKey("PostId")]
public Post Post { get; set; } = null!;
[Required]
public string AuthorId { get; set; } = string.Empty;
[ForeignKey("AuthorId")]
public AppUser Author { get; set; } = null!;
}
public class ApplicationDbContext : DbContext
{
public DbSet Posts => Set();
public DbSet Tags => Set();
public DbSet PostTags => Set();
public DbSet Comments => Set();
public ApplicationDbContext(DbContextOptions options) : base(options) {}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity().HasKey(pt => new { pt.PostId, pt.TagId });
builder.Entity()
.HasOne(pt => pt.Post)
.WithMany(p => p.PostTags)
.HasForeignKey(pt => pt.PostId)
.OnDelete(DeleteBehavior.Restrict);
builder.Entity()
.HasOne(pt => pt.Tag)
.WithMany(t => t.PostTags)
.HasForeignKey(pt => pt.TagId)
.OnDelete(DeleteBehavior.Restrict);
builder.Entity().HasData(new Post
{
Id = 1,
Title = "Seeded Post",
Content = "Initial content",
AuthorId = "seed-user-id",
});
builder.Entity().HasData(
new Tag { Id = 1, Name = "C#" },
new Tag { Id = 2, Name = "EF Core" });
builder.Entity().HasData(
new PostTag { PostId = 1, TagId = 1 },
new PostTag { PostId = 1, TagId = 2 });
}
}
public class PostService
{
private readonly ApplicationDbContext _context;
private readonly IHttpContextAccessor _httpContextAccessor;
public PostService(ApplicationDbContext context, IHttpContextAccessor accessor)
{
_context = context;
_httpContextAccessor = accessor;
}
private string? UserId =>
_httpContextAccessor.HttpContext?.User.FindFirst(ClaimTypes.NameIdentifier)?.Value;
public async Task> GetAllAsync() =>
await _context.Posts
.Include(p => p.Comments)
.Include(p => p.PostTags).ThenInclude(pt => pt.Tag)
.ToListAsync();
public async Task GetByIdAsync(int id) =>
await _context.Posts
.Include(p => p.Comments)
.Include(p => p.PostTags).ThenInclude(pt => pt.Tag)
.FirstOrDefaultAsync(p => p.Id == id);
public async Task CreateAsync(Post post, List tagIds)
{
post.AuthorId = UserId ?? string.Empty;
_context.Posts.Add(post);
await _context.SaveChangesAsync();
foreach (var tagId in tagIds)
{
_context.PostTags.Add(new PostTag { PostId = post.Id, TagId = tagId });
}
await _context.SaveChangesAsync();
}
public async Task DeleteAsync(int id)
{
var post = await _context.Posts.FindAsync(id);
if (post == null || post.AuthorId != UserId) return false;
_context.Posts.Remove(post);
await _context.SaveChangesAsync();
return true;
}
}
Ensure builder.Services.AddHttpContextAccessor(); is configured in Program.cs.
@inject AuthenticationStateProvider AuthenticationStateProvider
@code {
private string? UserId;
protected override async Task OnInitializedAsync()
{
var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();
var user = authState.User;
this.UserId = user.FindFirst(System.Security.Claims.ClaimTypes.NameIdentifier)?.Value;
}
}