Skip to content

Commit a9a64c7

Browse files
author
MPCoreDeveloper
committed
ef core
1 parent d48fc1f commit a9a64c7

File tree

8 files changed

+2293
-159
lines changed

8 files changed

+2293
-159
lines changed
Lines changed: 342 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,342 @@
1+
using Microsoft.EntityFrameworkCore;
2+
using Microsoft.Extensions.DependencyInjection;
3+
using SharpCoreDB.EntityFrameworkCore;
4+
using System.ComponentModel.DataAnnotations;
5+
using System.ComponentModel.DataAnnotations.Schema;
6+
7+
namespace SharpCoreDB.EntityFrameworkCore.Examples;
8+
9+
/// <summary>
10+
/// ASP.NET Core API example using SharpCoreDB with Entity Framework Core.
11+
///
12+
/// NOTE: This is a documentation/reference example showing how to use SharpCoreDB.EntityFrameworkCore
13+
/// in an ASP.NET Core application. To run this code:
14+
///
15+
/// 1. Create a new ASP.NET Core project:
16+
/// dotnet new webapi -n MyApp
17+
///
18+
/// 2. Add required packages:
19+
/// dotnet add package SharpCoreDB.EntityFrameworkCore
20+
/// dotnet add package Swashbuckle.AspNetCore
21+
///
22+
/// 3. Copy this code to Program.cs and build
23+
///
24+
/// This example demonstrates:
25+
/// - Minimal API endpoints
26+
/// - CRUD operations
27+
/// - Entity relationships
28+
/// - Modern C# 14 patterns
29+
/// - RESTful API design
30+
/// </summary>
31+
public class AspNetCoreExample
32+
{
33+
// Example code for Program.cs in ASP.NET Core application
34+
public static string GetExampleProgramCs()
35+
{
36+
return @"
37+
using Microsoft.EntityFrameworkCore;
38+
using SharpCoreDB.EntityFrameworkCore;
39+
40+
var builder = WebApplication.CreateBuilder(args);
41+
42+
// Add SharpCoreDB with EF Core
43+
builder.Services.AddDbContext<ProductDbContext>(options =>
44+
options.UseSharpCoreDB(
45+
builder.Configuration.GetConnectionString(""SharpCoreDB"")
46+
?? ""Data Source=./products.db;Password=SecurePassword123;Cache=Shared""));
47+
48+
builder.Services.AddEndpointsApiExplorer();
49+
builder.Services.AddSwaggerGen();
50+
51+
var app = builder.Build();
52+
53+
if (app.Environment.IsDevelopment())
54+
{
55+
app.UseSwagger();
56+
app.UseSwaggerUI();
57+
}
58+
59+
app.UseHttpsRedirection();
60+
61+
// Ensure database is created
62+
using (var scope = app.Services.CreateScope())
63+
{
64+
var context = scope.ServiceProvider.GetRequiredService<ProductDbContext>();
65+
await context.Database.EnsureCreatedAsync();
66+
}
67+
68+
// API Endpoints
69+
app.MapGet(""/api/products"", async (ProductDbContext db) =>
70+
await db.Products.Include(p => p.Category).AsNoTracking().ToListAsync())
71+
.WithName(""GetAllProducts"");
72+
73+
app.MapGet(""/api/products/{id}"", async (int id, ProductDbContext db) =>
74+
{
75+
var product = await db.Products.FindAsync(id);
76+
return product is not null ? Results.Ok(product) : Results.NotFound();
77+
})
78+
.WithName(""GetProductById"");
79+
80+
app.MapPost(""/api/products"", async (CreateProductRequest request, ProductDbContext db) =>
81+
{
82+
var product = new Product
83+
{
84+
Name = request.Name,
85+
Price = request.Price,
86+
CategoryId = request.CategoryId
87+
};
88+
db.Products.Add(product);
89+
await db.SaveChangesAsync();
90+
return Results.Created($""/api/products/{product.Id}"", product);
91+
})
92+
.WithName(""CreateProduct"");
93+
94+
app.Run();
95+
";
96+
}
97+
98+
// Standalone console example that works without ASP.NET Core
99+
public static async Task RunStandaloneExample()
100+
{
101+
Console.WriteLine("?? SharpCoreDB.EntityFrameworkCore - Standalone Console Example\n");
102+
103+
// Setup dependency injection
104+
var services = new ServiceCollection();
105+
106+
services.AddDbContext<ProductDbContext>(options =>
107+
options.UseSharpCoreDB("Data Source=./products.db;Password=SecurePassword123;Cache=Shared"));
108+
109+
var serviceProvider = services.BuildServiceProvider();
110+
111+
using var context = serviceProvider.GetRequiredService<ProductDbContext>();
112+
113+
// Ensure database is created
114+
await context.Database.EnsureCreatedAsync();
115+
116+
// Seed data
117+
await SeedData(context);
118+
119+
// Demonstrate CRUD operations
120+
await DemonstrateCrudOperations(context);
121+
122+
// Demonstrate relationships
123+
await DemonstrateRelationships(context);
124+
125+
Console.WriteLine("\n? Example completed successfully!");
126+
}
127+
128+
private static async Task SeedData(ProductDbContext context)
129+
{
130+
if (!await context.Categories.AnyAsync())
131+
{
132+
Console.WriteLine("?? Seeding database...\n");
133+
134+
var categories = new List<Category>
135+
{
136+
new() { Name = "Electronics", Description = "Electronic devices and accessories", CreatedAt = DateTime.UtcNow },
137+
new() { Name = "Books", Description = "Books and publications", CreatedAt = DateTime.UtcNow },
138+
new() { Name = "Clothing", Description = "Apparel and fashion", CreatedAt = DateTime.UtcNow }
139+
};
140+
141+
context.Categories.AddRange(categories);
142+
await context.SaveChangesAsync();
143+
144+
var products = new List<Product>
145+
{
146+
new() { Name = "Laptop", Description = "High-performance laptop", Price = 1299.99m, Stock = 10, IsActive = true, CategoryId = 1, CreatedAt = DateTime.UtcNow },
147+
new() { Name = "Mouse", Description = "Wireless mouse", Price = 29.99m, Stock = 50, IsActive = true, CategoryId = 1, CreatedAt = DateTime.UtcNow },
148+
new() { Name = "Keyboard", Description = "Mechanical keyboard", Price = 79.99m, Stock = 30, IsActive = true, CategoryId = 1, CreatedAt = DateTime.UtcNow },
149+
new() { Name = "C# Programming", Description = "Learn C# programming", Price = 49.99m, Stock = 20, IsActive = true, CategoryId = 2, CreatedAt = DateTime.UtcNow },
150+
new() { Name = "T-Shirt", Description = "Cotton t-shirt", Price = 19.99m, Stock = 100, IsActive = true, CategoryId = 3, CreatedAt = DateTime.UtcNow }
151+
};
152+
153+
context.Products.AddRange(products);
154+
await context.SaveChangesAsync();
155+
156+
Console.WriteLine($"? Seeded {categories.Count} categories and {products.Count} products\n");
157+
}
158+
}
159+
160+
private static async Task DemonstrateCrudOperations(ProductDbContext context)
161+
{
162+
Console.WriteLine("?? CRUD Operations:\n");
163+
164+
// CREATE
165+
var newProduct = new Product
166+
{
167+
Name = "Webcam",
168+
Description = "HD webcam",
169+
Price = 89.99m,
170+
Stock = 15,
171+
IsActive = true,
172+
CategoryId = 1,
173+
CreatedAt = DateTime.UtcNow
174+
};
175+
176+
context.Products.Add(newProduct);
177+
await context.SaveChangesAsync();
178+
Console.WriteLine($"? Created: {newProduct.Name} (ID: {newProduct.Id})");
179+
180+
// READ
181+
var product = await context.Products.FindAsync(newProduct.Id);
182+
Console.WriteLine($"? Read: {product?.Name} - {product?.Price:C}");
183+
184+
// UPDATE
185+
if (product is not null)
186+
{
187+
product.Price = 79.99m;
188+
await context.SaveChangesAsync();
189+
Console.WriteLine($"? Updated: {product.Name} - New price: {product.Price:C}");
190+
}
191+
192+
// DELETE (will delete later)
193+
Console.WriteLine($"? Product ready for deletion: {product?.Name}\n");
194+
}
195+
196+
private static async Task DemonstrateRelationships(ProductDbContext context)
197+
{
198+
Console.WriteLine("?? Relationships (Category ? Products):\n");
199+
200+
// Query with Include (eager loading)
201+
var categories = await context.Categories
202+
.Include(c => c.Products)
203+
.AsNoTracking()
204+
.ToListAsync();
205+
206+
foreach (var category in categories)
207+
{
208+
Console.WriteLine($"?? {category.Name} ({category.Products.Count} products):");
209+
foreach (var product in category.Products.Take(3))
210+
{
211+
Console.WriteLine($" - {product.Name}: {product.Price:C} (Stock: {product.Stock})");
212+
}
213+
Console.WriteLine();
214+
}
215+
}
216+
}
217+
218+
// ============================================================
219+
// ENTITY MODELS
220+
// ============================================================
221+
222+
/// <summary>
223+
/// Product entity with relationship to Category.
224+
/// </summary>
225+
public class Product
226+
{
227+
[Key]
228+
public int Id { get; set; }
229+
230+
[Required]
231+
[MaxLength(200)]
232+
public string Name { get; set; } = string.Empty;
233+
234+
public string Description { get; set; } = string.Empty;
235+
236+
[Column(TypeName = "DECIMAL")]
237+
public decimal Price { get; set; }
238+
239+
public int Stock { get; set; }
240+
241+
public bool IsActive { get; set; }
242+
243+
public DateTime CreatedAt { get; set; }
244+
245+
// Foreign key
246+
public int CategoryId { get; set; }
247+
248+
// Navigation property
249+
[ForeignKey(nameof(CategoryId))]
250+
public Category? Category { get; set; }
251+
}
252+
253+
/// <summary>
254+
/// Category entity with one-to-many relationship to Products.
255+
/// </summary>
256+
public class Category
257+
{
258+
[Key]
259+
public int Id { get; set; }
260+
261+
[Required]
262+
[MaxLength(100)]
263+
public string Name { get; set; } = string.Empty;
264+
265+
public string Description { get; set; } = string.Empty;
266+
267+
public DateTime CreatedAt { get; set; }
268+
269+
// Navigation property
270+
public ICollection<Product> Products { get; set; } = [];
271+
}
272+
273+
// ============================================================
274+
// REQUEST/RESPONSE DTOs (for ASP.NET Core)
275+
// ============================================================
276+
277+
public record CreateProductRequest(
278+
string Name,
279+
string Description,
280+
decimal Price,
281+
int Stock,
282+
int CategoryId
283+
);
284+
285+
public record UpdateProductRequest(
286+
string? Name = null,
287+
string? Description = null,
288+
decimal? Price = null,
289+
int? Stock = null,
290+
bool? IsActive = null,
291+
int? CategoryId = null
292+
);
293+
294+
public record CreateCategoryRequest(
295+
string Name,
296+
string Description
297+
);
298+
299+
// ============================================================
300+
// DB CONTEXT
301+
// ============================================================
302+
303+
/// <summary>
304+
/// Product database context using SharpCoreDB.
305+
/// Modern C# 14 with primary constructors.
306+
/// </summary>
307+
public class ProductDbContext(DbContextOptions<ProductDbContext> options) : DbContext(options)
308+
{
309+
public DbSet<Product> Products => Set<Product>();
310+
public DbSet<Category> Categories => Set<Category>();
311+
312+
protected override void OnModelCreating(ModelBuilder modelBuilder)
313+
{
314+
base.OnModelCreating(modelBuilder);
315+
316+
// Configure Category
317+
modelBuilder.Entity<Category>(entity =>
318+
{
319+
entity.ToTable("Categories");
320+
entity.HasKey(e => e.Id);
321+
entity.Property(e => e.Name).IsRequired().HasMaxLength(100);
322+
entity.HasIndex(e => e.Name).IsUnique();
323+
324+
// Relationship
325+
entity.HasMany(e => e.Products)
326+
.WithOne(p => p.Category)
327+
.HasForeignKey(p => p.CategoryId)
328+
.OnDelete(DeleteBehavior.Restrict);
329+
});
330+
331+
// Configure Product
332+
modelBuilder.Entity<Product>(entity =>
333+
{
334+
entity.ToTable("Products");
335+
entity.HasKey(e => e.Id);
336+
entity.Property(e => e.Name).IsRequired().HasMaxLength(200);
337+
entity.Property(e => e.Price).HasColumnType("DECIMAL");
338+
entity.HasIndex(e => e.Name);
339+
entity.HasIndex(e => e.CategoryId);
340+
});
341+
}
342+
}

0 commit comments

Comments
 (0)