Skip to content

Commit a990504

Browse files
committed
Added chapter 10 samples.
1 parent 0762359 commit a990504

10 files changed

+159
-76
lines changed

Chapter09/AttributeSample.cs

-73
This file was deleted.

Chapter10/Chapter10.csproj

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net8.0</TargetFramework>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<Nullable>enable</Nullable>
8+
</PropertyGroup>
9+
10+
</Project>

Chapter09/ColumnAttribute.cs Chapter10/ColumnAttribute.cs

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1-
namespace Chapter09
1+
namespace Chapter10
22
{
3+
/*
4+
ColumnAttribute'u sadece field ve property türlerine uygulanabilir.
5+
Attribute'lar Attribute türünden türemelidir.
6+
*/
37
[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field)]
48
internal class ColumnAttribute
59
: Attribute

Chapter10/DataType.cs

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
namespace Cshapter10;
2+
3+
internal class DataType
4+
{
5+
}
6+
internal class SqlDataType : DataType
7+
{
8+
public const string Text = "nvarchar";
9+
public const string Decimal = "decimal";
10+
public const string Bool = "bit";
11+
public const string BigInt = "bigint";
12+
}

Chapter10/MigrationProvider.cs

+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
using Chapter10.Model;
2+
using Cshapter10;
3+
using System.Reflection;
4+
using System.Text;
5+
6+
namespace Chapter10;
7+
8+
/*
9+
Kendisine verilen nesneler için gerekli SQL Tablo oluşturma script'lerini üretir.
10+
Bir nevi otomatik kod üretici olarak düşünebiliriz.
11+
Kendisine ait bir runtime'ı vardır. Dolayısıyla çalışma zamanında okuduğu sınıflar için
12+
Create Table script'leri hazırlar.
13+
14+
EF'in Migration Tool'u (CLI) göz önüne getirilebilir.
15+
*/
16+
internal class MigrationProvider
17+
{
18+
/*
19+
CrateTableScript metodu EntityBase sınıfından türemiş sınıflarla çalışacak şekilde
20+
tasarlanmıştır. Görevi, instance örneğinin Table ve Column attribute'larını tarayıp
21+
uygun Create Table script'ini üretmektir
22+
*/
23+
public static string CreateTableScript<T>(T instance)
24+
where T : EntityBase
25+
{
26+
var builder = new StringBuilder();
27+
builder.Append("CREATE OR ALTER TABLE ");
28+
var instanceType = typeof(T); // Burada instance değişkeni ile gelen type bilgisini yakalarız
29+
30+
// TableAttribute'u yakalıyoruz
31+
var tableAttribute = instanceType.GetCustomAttribute<TableAttribute>();
32+
if (tableAttribute != null) // Eğer uygulanmışsa şema adı ve tablo adını kullan
33+
{
34+
builder.AppendLine($"{tableAttribute.Schema}.{tableAttribute.Name} (");
35+
}
36+
else // Eğer TableAttribute uygulanmamışsa varsayılan tablo adı için sınıf adı kullanılabilir
37+
{
38+
builder.AppendLine($"{instanceType.Name} (");
39+
}
40+
41+
// Type üzerindeki tüm property üyelerini dolaşıyoruz.
42+
foreach (var property in instanceType.GetProperties())
43+
{
44+
// Eğer bu özellik ColumnAttribute'u uygulamışsa kolonları ona göre ekliyoruz
45+
var columnAttribute = property.GetCustomAttribute<ColumnAttribute>();
46+
if (columnAttribute != null)
47+
{
48+
// Text türünde bir alansa length bilgisi gerekeceğinden bu tip bir ayrıma gittik
49+
if (columnAttribute.DataType == SqlDataType.Text)
50+
{
51+
builder.AppendLine($"\t{columnAttribute.Name} {columnAttribute.DataType}({columnAttribute.Length}),");
52+
}else
53+
{
54+
builder.AppendLine($"\t{columnAttribute.Name} {columnAttribute.DataType},");
55+
}
56+
}
57+
else
58+
{
59+
builder.AppendLine($"\t{property.Name},");
60+
//TODO@buraksenyurt Eğer ColumnAttribute uygulanmadıysa özellik tipine bakarak varsayılan bir tanımlama yapılmalı
61+
}
62+
}
63+
64+
var script = builder.ToString()[..(builder.Length - 3)] + "\n)\nGo";
65+
return script;
66+
}
67+
68+
internal static void SaveScript(string script, string filePath)
69+
{
70+
var fPath = Path.Combine(Environment.CurrentDirectory,filePath);
71+
File.WriteAllText(fPath,script);
72+
}
73+
}

Chapter10/Model/EntityBase.cs

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
namespace Chapter10.Model;
2+
3+
internal class EntityBase
4+
{
5+
}

Chapter10/Model/Product.cs

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
using Cshapter10;
2+
3+
namespace Chapter10.Model;
4+
5+
/*
6+
Product sınıfını MigrationProvider senaryo gereği bir runtime olarak okur.
7+
Amacı bu sınıfa ve üyelerine bakıp bir SQL Table Create script' i oluşturmaktır.
8+
Bunun için Table ve Column Attribute sınıfları ile, runtime'a ekstra bilgiler taşınır.
9+
Örneğin, tablo adı ve şeması ne olacak, property'ler kolon haline çevrilirken hangi
10+
veri türünden olacak vs
11+
*/
12+
13+
[Table(Schema = "Catalog", Name = "Products")]
14+
internal class Product
15+
: EntityBase
16+
{
17+
[Column(Name = "p_id", DataType = SqlDataType.BigInt, PrimaryKey = true)]
18+
public int Id { get; set; }
19+
[Column(Name = "p_title", DataType = SqlDataType.Text, Length = 50)]
20+
public string Title { get; set; }
21+
[Column(Name = "p_list_price", DataType = SqlDataType.Decimal)]
22+
public decimal ListPrice { get; set; }
23+
[Column(Name = "p_in_stock", DataType = SqlDataType.Bool)]
24+
public bool InStock { get; set; }
25+
}

Chapter10/Program.cs

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
using Chapter10.Model;
2+
3+
namespace Chapter10
4+
{
5+
internal class Program
6+
{
7+
static void Main()
8+
{
9+
Product product = new Product
10+
{
11+
Id = 1,
12+
Title = "Dolma kalem",
13+
InStock = true,
14+
ListPrice = 10.0M
15+
};
16+
var script = MigrationProvider.CreateTableScript(product); // product isimli nesne örneği için Create Table script'ini üret
17+
Console.WriteLine($"{script}");
18+
MigrationProvider.SaveScript(script,"CreateProduct.sql");
19+
}
20+
}
21+
}

Chapter09/TableAttribute.cs Chapter10/TableAttribute.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
namespace Chapter09
1+
namespace Chapter10
22
{
33
/*
44
Attribute sınıfları Attribute kelimesi ile bitecek şekilde isimlendirilir ve Attribute sınıfından türer.
@@ -8,7 +8,7 @@ ColumnAttribute ise sadece Property'lere veya Field'lara uygulanabilir.
88
*/
99
[AttributeUsage(AttributeTargets.Class)]
1010
internal class TableAttribute
11-
: Attribute
11+
: Attribute
1212
{
1313
public string Schema { get; set; }
1414
public string Name { get; set; }

ProgrammingWithCSharp.sln

+6
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Learning.Delegates", "Learn
8585
EndProject
8686
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Chapter09", "Chapter09\Chapter09.csproj", "{67C7D149-C145-45E5-BD2B-2386D7C5657A}"
8787
EndProject
88+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Chapter10", "Chapter10\Chapter10.csproj", "{D5A2D810-7D73-4889-9B9C-220BEFC29B47}"
89+
EndProject
8890
Global
8991
GlobalSection(SolutionConfigurationPlatforms) = preSolution
9092
Debug|Any CPU = Debug|Any CPU
@@ -223,6 +225,10 @@ Global
223225
{67C7D149-C145-45E5-BD2B-2386D7C5657A}.Debug|Any CPU.Build.0 = Debug|Any CPU
224226
{67C7D149-C145-45E5-BD2B-2386D7C5657A}.Release|Any CPU.ActiveCfg = Release|Any CPU
225227
{67C7D149-C145-45E5-BD2B-2386D7C5657A}.Release|Any CPU.Build.0 = Release|Any CPU
228+
{D5A2D810-7D73-4889-9B9C-220BEFC29B47}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
229+
{D5A2D810-7D73-4889-9B9C-220BEFC29B47}.Debug|Any CPU.Build.0 = Debug|Any CPU
230+
{D5A2D810-7D73-4889-9B9C-220BEFC29B47}.Release|Any CPU.ActiveCfg = Release|Any CPU
231+
{D5A2D810-7D73-4889-9B9C-220BEFC29B47}.Release|Any CPU.Build.0 = Release|Any CPU
226232
EndGlobalSection
227233
GlobalSection(SolutionProperties) = preSolution
228234
HideSolutionNode = FALSE

0 commit comments

Comments
 (0)