<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>ErcanOPAK &#8211; Bits of .NET</title>
	<atom:link href="http://blog.ercanopak.com/author/26821acd6c28c7fc443850f1c5320611/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.ercanopak.com</link>
	<description>Daily micro-tips for C#, SQL, performance, and scalable backend engineering.</description>
	<lastBuildDate>Mon, 30 Mar 2026 17:52:20 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>http://blog.ercanopak.com/wp-content/uploads/2018/06/cropped-EO_LOGO_32-32x32.png</url>
	<title>ErcanOPAK &#8211; Bits of .NET</title>
	<link>http://blog.ercanopak.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>C#: Use Init-Only Setters for Immutable Objects After Construction</title>
		<link>http://blog.ercanopak.com/c-use-init-only-setters-for-immutable-objects-after-construction/</link>
					<comments>http://blog.ercanopak.com/c-use-init-only-setters-for-immutable-objects-after-construction/#respond</comments>
		
		<dc:creator><![CDATA[ErcanOPAK]]></dc:creator>
		<pubDate>Mon, 30 Mar 2026 17:52:20 +0000</pubDate>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[C# 11]]></category>
		<category><![CDATA[C# 9]]></category>
		<category><![CDATA[DTOs]]></category>
		<category><![CDATA[immutability]]></category>
		<category><![CDATA[Init-Only Setters]]></category>
		<category><![CDATA[Modern C#]]></category>
		<category><![CDATA[Object Initializers]]></category>
		<category><![CDATA[Required Members]]></category>
		<category><![CDATA[Value Objects]]></category>
		<guid isPermaLink="false">http://blog.ercanopak.com/c-use-init-only-setters-for-immutable-objects-after-construction/</guid>

					<description><![CDATA[🔒 Immutable After Creation Want immutable objects but like object initializers? Init-only setters (C# 9) allow setting properties during initialization only. Read-only after construction. The Old Dilemma // Option 1: Mutable properties (not safe) public class Person { public string Name { get; set; } public int Age { get; set; } } var person [&#8230;]]]></description>
										<content:encoded><![CDATA[<div style="background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); color: white; padding: 50px 40px; border-radius: 16px; margin: 40px 0; box-shadow: 0 20px 60px rgba(0,0,0,0.3);">
<h2 style="margin: 0 0 20px 0; font-size: 2.8em; font-weight: 800; line-height: 1.2;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f512.png" alt="🔒" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Immutable After Creation</h2>
<p style="font-size: 1.4em; line-height: 1.8; margin: 0; opacity: 0.95;">Want immutable objects but like object initializers? <strong>Init-only setters</strong> (C# 9) allow setting properties during initialization only. Read-only after construction.</p>
</p></div>
<h3 style="color: #2c3e50; font-size: 2.2em; margin: 50px 0 30px 0; font-weight: 700; border-left: 5px solid #f5576c; padding-left: 20px;">The Old Dilemma</h3>
<pre class="EnlighterJSRAW" data-enlighter-language="csharp">
// Option 1: Mutable properties (not safe)
public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

var person = new Person { Name = "Alice", Age = 30 };
person.Age = 31;  // <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Works, but object is mutable

// Option 2: Read-only with constructor (verbose)
public class Person
{
    public string Name { get; }
    public int Age { get; }

    public Person(string name, int age)
    {
        Name = name;
        Age = age;
    }
}

var person = new Person("Alice", 30);  // Can't use object initializer <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/274c.png" alt="❌" class="wp-smiley" style="height: 1em; max-height: 1em;" />

// Option 3: Private setter (still allows mutation in class)
public class Person
{
    public string Name { get; private set; }
    public int Age { get; private set; }
}

// All have tradeoffs!
</pre>
<h3 style="color: #2c3e50; font-size: 2.2em; margin: 50px 0 30px 0; font-weight: 700; border-left: 5px solid #27ae60; padding-left: 20px;">Init-Only Setters Solution</h3>
<pre class="EnlighterJSRAW" data-enlighter-language="csharp">
// <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Best of both worlds!
public class Person
{
    public string Name { get; init; }
    public int Age { get; init; }
}

// Can use object initializer
var person = new Person 
{ 
    Name = "Alice", 
    Age = 30 
};

// But can't modify after construction
person.Age = 31;  // <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/274c.png" alt="❌" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Compile error: Init-only property can only be set in initializer

// Perfect for immutable objects!
</pre>
<div style="background: #f8f9fa; padding: 40px; border-radius: 12px; margin: 40px 0; border: 2px solid #f093fb;">
<h4 style="color: #f5576c; margin-top: 0; font-size: 1.7em; font-weight: 700;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3af.png" alt="🎯" class="wp-smiley" style="height: 1em; max-height: 1em;" /> With Constructor</h4>
<pre class="EnlighterJSRAW" data-enlighter-language="csharp">
public class Person
{
    public string Name { get; init; }
    public int Age { get; init; }
    public DateTime CreatedAt { get; init; }

    public Person()
    {
        CreatedAt = DateTime.UtcNow;  // <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Can set in constructor
    }
}

var person = new Person 
{ 
    Name = "Alice",
    Age = 30
};

Console.WriteLine(person.CreatedAt);  // Set automatically in constructor
// But CreatedAt can also be overridden in initializer if needed
</pre>
</p></div>
<h3 style="color: #2c3e50; font-size: 2.2em; margin: 50px 0 30px 0; font-weight: 700; border-left: 5px solid #667eea; padding-left: 20px;">Validation with Init</h3>
<pre class="EnlighterJSRAW" data-enlighter-language="csharp">
public class Email
{
    private string _value;

    public string Value
    {
        get => _value;
        init
        {
            if (string.IsNullOrWhiteSpace(value))
                throw new ArgumentException("Email cannot be empty");
            
            if (!value.Contains('@'))
                throw new ArgumentException("Invalid email format");
            
            _value = value;
        }
    }
}

var email = new Email { Value = "alice@example.com" };  // <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Valid
var invalid = new Email { Value = "not-an-email" };      // <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/274c.png" alt="❌" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Throws exception

// After creation, immutable
// email.Value = "new@example.com";  // <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/274c.png" alt="❌" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Compile error
</pre>
<h3 style="color: #2c3e50; font-size: 2.2em; margin: 50px 0 30px 0; font-weight: 700; border-left: 5px solid #f39c12; padding-left: 20px;">Required Members (C# 11)</h3>
<pre class="EnlighterJSRAW" data-enlighter-language="csharp">
// Combine init with required
public class User
{
    public required string Email { get; init; }
    public required string Name { get; init; }
    public string? PhoneNumber { get; init; }  // Optional
}

// <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Must set required properties
var user = new User 
{ 
    Email = "alice@example.com",
    Name = "Alice"
};

// <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/274c.png" alt="❌" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Compile error: Required member 'Email' must be set
var invalid = new User { Name = "Alice" };
</pre>
<div style="background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); color: white; padding: 35px; border-radius: 12px; margin: 40px 0;">
<h4 style="margin-top: 0; font-size: 1.7em; font-weight: 700;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f310.png" alt="🌐" class="wp-smiley" style="height: 1em; max-height: 1em;" /> DTOs and API Models</h4>
<pre style="background: rgba(0,0,0,0.3); color: #fff; padding: 25px; border-radius: 8px; font-size: 1.05em; line-height: 1.8;">
// Perfect for API request/response DTOs
public class CreateUserRequest
{
    public required string Email { get; init; }
    public required string Password { get; init; }
    public required string Name { get; init; }
    public string? PhoneNumber { get; init; }
}

public class UserResponse
{
    public required int Id { get; init; }
    public required string Email { get; init; }
    public required string Name { get; init; }
    public required DateTime CreatedAt { get; init; }
}

// Controller
[HttpPost("users")]
public async Task<UserResponse> CreateUser(CreateUserRequest request)
{
    var user = await _userService.CreateAsync(request);
    
    return new UserResponse
    {
        Id = user.Id,
        Email = user.Email,
        Name = user.Name,
        CreatedAt = user.CreatedAt
    };
}

// Response is immutable - thread-safe!
</pre>
</p></div>
<h3 style="color: #2c3e50; font-size: 2.2em; margin: 50px 0 30px 0; font-weight: 700; border-left: 5px solid #27ae60; padding-left: 20px;">With Record Types</h3>
<pre class="EnlighterJSRAW" data-enlighter-language="csharp">
// Records have init by default
public record Person(string Name, int Age);

// Same as:
public record Person
{
    public string Name { get; init; }
    public int Age { get; init; }
    
    public Person(string name, int age)
    {
        Name = name;
        Age = age;
    }
}

// Use with expressions for non-destructive mutation
var person1 = new Person("Alice", 30);
var person2 = person1 with { Age = 31 };

// person1 unchanged, person2 has new age
</pre>
<div style="background: linear-gradient(135deg, #d4edda 0%, #c3e6cb 100%); padding: 35px; border-radius: 12px; margin: 40px 0; border-left: 5px solid #28a745;">
<h4 style="color: #155724; margin-top: 0; font-size: 1.7em; font-weight: 700;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Benefits</h4>
<ul style="color: #155724; font-size: 1.15em; line-height: 2.2; margin: 20px 0;">
<li><strong>Object initializer syntax:</strong> Clean, readable</li>
<li><strong>Immutability:</strong> Thread-safe, predictable</li>
<li><strong>Required members:</strong> Compiler enforces initialization</li>
<li><strong>Validation:</strong> Can validate in init setter</li>
<li><strong>No constructor bloat:</strong> Avoid 10-parameter constructors</li>
</ul></div>
<div style="background: linear-gradient(135deg, #fff3cd 0%, #ffe69c 100%); border-left: 5px solid #ffc107; padding: 35px; margin: 50px 0; border-radius: 12px;">
<h4 style="color: #856404; margin-top: 0; font-size: 1.7em; font-weight: 700;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4a1.png" alt="💡" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Best Practices</h4>
<ul style="color: #856404; font-size: 1.15em; line-height: 2.2; margin: 20px 0;">
<li><strong>Use for DTOs:</strong> API models, configuration objects</li>
<li><strong>Combine with required:</strong> Enforce mandatory properties</li>
<li><strong>Add validation:</strong> In init setters when needed</li>
<li><strong>Prefer records:</strong> For data-centric types</li>
<li><strong>Document intent:</strong> Use init to signal immutability</li>
</ul></div>
<div style="background: #f8f9fa; padding: 40px; border-radius: 12px; margin: 40px 0; border: 2px solid #f093fb;">
<h4 style="color: #f5576c; margin-top: 0; font-size: 1.7em; font-weight: 700;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3af.png" alt="🎯" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Real-World Example</h4>
<pre class="EnlighterJSRAW" data-enlighter-language="csharp">
// Configuration object
public class DatabaseConfig
{
    public required string ConnectionString { get; init; }
    public required string DatabaseName { get; init; }
    public int MaxPoolSize { get; init; } = 100;
    public int CommandTimeout { get; init; } = 30;
    public bool EnableRetry { get; init; } = true;
}

// Usage
var config = new DatabaseConfig
{
    ConnectionString = "Server=localhost;Database=mydb",
    DatabaseName = "mydb",
    MaxPoolSize = 200
};

// Immutable after creation - safe to pass around
await InitializeDatabaseAsync(config);

// Can't accidentally change config
// config.MaxPoolSize = 300;  // <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/274c.png" alt="❌" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Compile error

// Value object
public class Money
{
    public required decimal Amount { get; init; }
    public required string Currency { get; init; }

    public Money Add(Money other)
    {
        if (Currency != other.Currency)
            throw new InvalidOperationException("Currency mismatch");
        
        return new Money 
        { 
            Amount = Amount + other.Amount,
            Currency = Currency
        };
    }
}

var price1 = new Money { Amount = 100m, Currency = "USD" };
var price2 = new Money { Amount = 50m, Currency = "USD" };
var total = price1.Add(price2);

// All Money objects immutable - safe!
</pre>
</p></div>
<blockquote style="background: linear-gradient(to right, #fce4ec, #f8bbd0); border-left: 6px solid #e91e63; padding: 40px; margin: 50px 0; border-radius: 12px;">
<p style="font-size: 1.5em; line-height: 1.9; margin: 0; color: #880e4f; font-style: italic; font-weight: 500;">&#8220;Converted all configuration classes to init-only properties. Thread-safety bugs disappeared. Code cleaner with object initializers. Required keyword catches missing configs at compile-time.&#8221;</p>
<footer style="margin-top: 20px; color: #ad1457; font-size: 1.15em; font-weight: 600;">— Senior .NET Engineer</footer>
</blockquote>
]]></content:encoded>
					
					<wfw:commentRss>http://blog.ercanopak.com/c-use-init-only-setters-for-immutable-objects-after-construction/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>C#: Use Expression-Bodied Members for Concise Single-Line Methods</title>
		<link>http://blog.ercanopak.com/c-use-expression-bodied-members-for-concise-single-line-methods/</link>
					<comments>http://blog.ercanopak.com/c-use-expression-bodied-members-for-concise-single-line-methods/#respond</comments>
		
		<dc:creator><![CDATA[ErcanOPAK]]></dc:creator>
		<pubDate>Mon, 30 Mar 2026 17:52:14 +0000</pubDate>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[C# 6]]></category>
		<category><![CDATA[C# 7]]></category>
		<category><![CDATA[C# Tips]]></category>
		<category><![CDATA[Clean Code]]></category>
		<category><![CDATA[Code Style]]></category>
		<category><![CDATA[Concise Code]]></category>
		<category><![CDATA[Expression-Bodied Members]]></category>
		<category><![CDATA[Lambda Expressions]]></category>
		<category><![CDATA[Modern C#]]></category>
		<guid isPermaLink="false">http://blog.ercanopak.com/c-use-expression-bodied-members-for-concise-single-line-methods/</guid>

					<description><![CDATA[➡️ Lambda-Style Everything Simple methods with { return x; }? Verbose. Expression-bodied members use => for methods, properties, constructors. One line replaces five. Expression-Bodied Methods // ❌ Traditional method syntax public string GetFullName() { return $"{FirstName} {LastName}"; } // ✅ Expression-bodied method public string GetFullName() => $"{FirstName} {LastName}"; // More examples public int Add(int a, [&#8230;]]]></description>
										<content:encoded><![CDATA[<div style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 50px 40px; border-radius: 16px; margin: 40px 0; box-shadow: 0 20px 60px rgba(0,0,0,0.3);">
<h2 style="margin: 0 0 20px 0; font-size: 2.8em; font-weight: 800; line-height: 1.2;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/27a1.png" alt="➡" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Lambda-Style Everything</h2>
<p style="font-size: 1.4em; line-height: 1.8; margin: 0; opacity: 0.95;">Simple methods with { return x; }? Verbose. <strong>Expression-bodied members</strong> use => for methods, properties, constructors. One line replaces five.</p>
</p></div>
<h3 style="color: #2c3e50; font-size: 2.2em; margin: 50px 0 30px 0; font-weight: 700; border-left: 5px solid #764ba2; padding-left: 20px;">Expression-Bodied Methods</h3>
<pre class="EnlighterJSRAW" data-enlighter-language="csharp">
// <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/274c.png" alt="❌" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Traditional method syntax
public string GetFullName()
{
    return $"{FirstName} {LastName}";
}

// <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Expression-bodied method
public string GetFullName() => $"{FirstName} {LastName}";

// More examples
public int Add(int a, int b) => a + b;

public bool IsAdult() => Age >= 18;

public void PrintMessage() => Console.WriteLine("Hello");

public async Task<User> GetUserAsync(int id) => await _repository.GetByIdAsync(id);
</pre>
<div style="background: #f8f9fa; padding: 40px; border-radius: 12px; margin: 40px 0; border: 2px solid #667eea;">
<h4 style="color: #667eea; margin-top: 0; font-size: 1.7em; font-weight: 700;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3af.png" alt="🎯" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Expression-Bodied Properties</h4>
<pre class="EnlighterJSRAW" data-enlighter-language="csharp">
public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public DateTime BirthDate { get; set; }

    // <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/274c.png" alt="❌" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Traditional read-only property
    public string FullName
    {
        get
        {
            return $"{FirstName} {LastName}";
        }
    }

    // <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Expression-bodied property
    public string FullName => $"{FirstName} {LastName}";

    // More examples
    public int Age => (int)((DateTime.Now - BirthDate).TotalDays / 365.25);
    
    public bool IsAdult => Age >= 18;
    
    public string Initials => $"{FirstName[0]}{LastName[0]}";
}

// Expression-bodied getter and setter (C# 7+)
private string _name;

public string Name
{
    get => _name;
    set => _name = value?.Trim() ?? throw new ArgumentNullException();
}
</pre>
</p></div>
<h3 style="color: #2c3e50; font-size: 2.2em; margin: 50px 0 30px 0; font-weight: 700; border-left: 5px solid #f39c12; padding-left: 20px;">Expression-Bodied Constructors</h3>
<pre class="EnlighterJSRAW" data-enlighter-language="csharp">
public class Point
{
    public int X { get; }
    public int Y { get; }

    // <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/274c.png" alt="❌" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Traditional constructor
    public Point(int x, int y)
    {
        X = x;
        Y = y;
    }

    // <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Expression-bodied constructor
    public Point(int x, int y) => (X, Y) = (x, y);
}

// More examples
public class Logger
{
    private readonly ILoggerFactory _factory;

    public Logger(ILoggerFactory factory) => _factory = factory ?? throw new ArgumentNullException(nameof(factory));
}
</pre>
<h3 style="color: #2c3e50; font-size: 2.2em; margin: 50px 0 30px 0; font-weight: 700; border-left: 5px solid #27ae60; padding-left: 20px;">Expression-Bodied Finalizers &#038; Indexers</h3>
<pre class="EnlighterJSRAW" data-enlighter-language="csharp">
// Expression-bodied finalizer
~MyClass() => Console.WriteLine("Finalizing");

// Expression-bodied indexer
public class Collection<T>
{
    private readonly T[] _items;

    public Collection(T[] items) => _items = items;

    // <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/274c.png" alt="❌" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Traditional indexer
    public T this[int index]
    {
        get { return _items[index]; }
        set { _items[index] = value; }
    }

    // <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Expression-bodied indexer
    public T this[int index]
    {
        get => _items[index];
        set => _items[index] = value;
    }
}
</pre>
<div style="background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); color: white; padding: 35px; border-radius: 12px; margin: 40px 0;">
<h4 style="margin-top: 0; font-size: 1.7em; font-weight: 700;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f527.png" alt="🔧" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Complete Class Example</h4>
<pre style="background: rgba(0,0,0,0.3); color: #fff; padding: 25px; border-radius: 8px; font-size: 1.05em; line-height: 1.8;">
public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public decimal Price { get; set; }
    public decimal Cost { get; set; }
    public int Stock { get; set; }

    // Expression-bodied properties
    public decimal Margin => Price - Cost;
    public decimal MarginPercent => (Margin / Price) * 100;
    public bool InStock => Stock > 0;
    public bool LowStock => Stock < 10 &#038;&#038; Stock > 0;

    // Expression-bodied methods
    public decimal CalculateRevenue(int quantity) => Price * quantity;
    
    public decimal CalculateProfit(int quantity) => Margin * quantity;
    
    public bool CanFulfillOrder(int quantity) => Stock >= quantity;
    
    public void Restock(int amount) => Stock += amount;
    
    public void Sell(int quantity) => Stock -= quantity;

    // ToString
    public override string ToString() => $"Product: {Name} (${Price:F2})";
}

// Usage
var product = new Product 
{ 
    Name = "Widget", 
    Price = 100m, 
    Cost = 60m, 
    Stock = 50 
};

Console.WriteLine(product.Margin);         // 40
Console.WriteLine(product.MarginPercent);  // 40
Console.WriteLine(product.LowStock);       // false
Console.WriteLine(product.CalculateProfit(10));  // 400
</pre>
</p></div>
<div style="background: linear-gradient(135deg, #d4edda 0%, #c3e6cb 100%); padding: 35px; border-radius: 12px; margin: 40px 0; border-left: 5px solid #28a745;">
<h4 style="color: #155724; margin-top: 0; font-size: 1.7em; font-weight: 700;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> When to Use</h4>
<ul style="color: #155724; font-size: 1.15em; line-height: 2.2; margin: 20px 0;">
<li><strong>Single-expression methods:</strong> One return statement</li>
<li><strong>Read-only properties:</strong> Computed values</li>
<li><strong>Simple getters/setters:</strong> Validation, transformation</li>
<li><strong>Factory methods:</strong> new Constructor(params)</li>
<li><strong>LINQ projections:</strong> Clean Select() statements</li>
</ul></div>
<div style="background: linear-gradient(135deg, #fff3cd 0%, #ffe69c 100%); border-left: 5px solid #ffc107; padding: 35px; margin: 50px 0; border-radius: 12px;">
<h4 style="color: #856404; margin-top: 0; font-size: 1.7em; font-weight: 700;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/26a0.png" alt="⚠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> When NOT to Use</h4>
<ul style="color: #856404; font-size: 1.15em; line-height: 2.2; margin: 20px 0;">
<li><strong>Multiple statements:</strong> Stick to traditional syntax</li>
<li><strong>Complex logic:</strong> Readability over conciseness</li>
<li><strong>Long expressions:</strong> Line gets too long (> 120 chars)</li>
<li><strong>Debugging:</strong> Can&#8217;t set breakpoint inside expression</li>
</ul></div>
<div style="background: #f8f9fa; padding: 40px; border-radius: 12px; margin: 40px 0; border: 2px solid #667eea;">
<h4 style="color: #667eea; margin-top: 0; font-size: 1.7em; font-weight: 700;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4a1.png" alt="💡" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Before &#038; After Comparison</h4>
<pre class="EnlighterJSRAW" data-enlighter-language="csharp">
// <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/274c.png" alt="❌" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Before: 30 lines
public class Calculator
{
    public int Add(int a, int b)
    {
        return a + b;
    }

    public int Subtract(int a, int b)
    {
        return a - b;
    }

    public int Multiply(int a, int b)
    {
        return a * b;
    }

    public double Divide(int a, int b)
    {
        return (double)a / b;
    }

    public bool IsEven(int number)
    {
        return number % 2 == 0;
    }

    public int Square(int number)
    {
        return number * number;
    }
}

// <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> After: 10 lines
public class Calculator
{
    public int Add(int a, int b) => a + b;
    public int Subtract(int a, int b) => a - b;
    public int Multiply(int a, int b) => a * b;
    public double Divide(int a, int b) => (double)a / b;
    public bool IsEven(int number) => number % 2 == 0;
    public int Square(int number) => number * number;
}

// 67% less code, same functionality!
</pre>
</p></div>
<blockquote style="background: linear-gradient(to right, #e8eaf6, #c5cae9); border-left: 6px solid #5c6bc0; padding: 40px; margin: 50px 0; border-radius: 12px;">
<p style="font-size: 1.5em; line-height: 1.9; margin: 0; color: #1a237e; font-style: italic; font-weight: 500;">&#8220;Refactored utility classes to expression-bodied members. Code reduced 40%. Readability improved. Team adopted it everywhere. Now standard in our style guide.&#8221;</p>
<footer style="margin-top: 20px; color: #283593; font-size: 1.15em; font-weight: 600;">— C# Developer</footer>
</blockquote>
]]></content:encoded>
					
					<wfw:commentRss>http://blog.ercanopak.com/c-use-expression-bodied-members-for-concise-single-line-methods/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>C#: Enable Nullable Reference Types to Eliminate Null Reference Exceptions</title>
		<link>http://blog.ercanopak.com/c-enable-nullable-reference-types-to-eliminate-null-reference-exceptions/</link>
					<comments>http://blog.ercanopak.com/c-enable-nullable-reference-types-to-eliminate-null-reference-exceptions/#respond</comments>
		
		<dc:creator><![CDATA[ErcanOPAK]]></dc:creator>
		<pubDate>Mon, 30 Mar 2026 17:52:07 +0000</pubDate>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[Best Practices]]></category>
		<category><![CDATA[C# 8]]></category>
		<category><![CDATA[Code Quality]]></category>
		<category><![CDATA[Compiler Warnings]]></category>
		<category><![CDATA[Modern C#]]></category>
		<category><![CDATA[Null Safety]]></category>
		<category><![CDATA[Nullable Reference Types]]></category>
		<category><![CDATA[NullReferenceException]]></category>
		<category><![CDATA[Type Safety]]></category>
		<guid isPermaLink="false">http://blog.ercanopak.com/c-enable-nullable-reference-types-to-eliminate-null-reference-exceptions/</guid>

					<description><![CDATA[🛡️ No More NullReferenceException NullReferenceException killing your app? Can&#8217;t tell if variable can be null? Nullable reference types (C# 8+) make nullability explicit. Compiler warns about potential null errors. The Null Problem // Before nullable reference types public class UserService { public string GetUserName(int userId) { var user = _repository.GetById(userId); // Could return null! return [&#8230;]]]></description>
										<content:encoded><![CDATA[<div style="background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); color: white; padding: 50px 40px; border-radius: 16px; margin: 40px 0; box-shadow: 0 20px 60px rgba(0,0,0,0.3);">
<h2 style="margin: 0 0 20px 0; font-size: 2.8em; font-weight: 800; line-height: 1.2;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f6e1.png" alt="🛡" class="wp-smiley" style="height: 1em; max-height: 1em;" /> No More NullReferenceException</h2>
<p style="font-size: 1.4em; line-height: 1.8; margin: 0; opacity: 0.95;">NullReferenceException killing your app? Can&#8217;t tell if variable can be null? <strong>Nullable reference types</strong> (C# 8+) make nullability explicit. Compiler warns about potential null errors.</p>
</p></div>
<h3 style="color: #2c3e50; font-size: 2.2em; margin: 50px 0 30px 0; font-weight: 700; border-left: 5px solid #00f2fe; padding-left: 20px;">The Null Problem</h3>
<pre class="EnlighterJSRAW" data-enlighter-language="csharp">
// Before nullable reference types
public class UserService
{
    public string GetUserName(int userId)
    {
        var user = _repository.GetById(userId);  // Could return null!
        return user.Name;  // <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4a5.png" alt="💥" class="wp-smiley" style="height: 1em; max-height: 1em;" /> NullReferenceException if user is null
    }
}

// No compiler warning!
// Crashes at runtime
// "The billion dollar mistake" - Tony Hoare
</pre>
<h3 style="color: #2c3e50; font-size: 2.2em; margin: 50px 0 30px 0; font-weight: 700; border-left: 5px solid #27ae60; padding-left: 20px;">Enable Nullable Reference Types</h3>
<pre class="EnlighterJSRAW" data-enlighter-language="xml">
<!-- In .csproj -->
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>net8.0</TargetFramework>
    <Nullable>enable</Nullable>  <!-- Enable nullable warnings -->
  </PropertyGroup>
</Project>

<!-- Or in specific files -->
#nullable enable  // At top of .cs file
</pre>
<pre class="EnlighterJSRAW" data-enlighter-language="csharp">
// After enabling nullable reference types
public class UserService
{
    // Non-nullable: Must never be null
    public string GetUserName(int userId)
    {
        User? user = _repository.GetById(userId);  // User? = nullable
        return user.Name;  // <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/26a0.png" alt="⚠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Compiler warning: Possible null reference
    }
    
    // Fixed version
    public string GetUserName(int userId)
    {
        User? user = _repository.GetById(userId);
        
        if (user == null)
        {
            throw new UserNotFoundException(userId);
        }
        
        return user.Name;  // <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> No warning - null checked
    }
    
    // Or return nullable
    public string? GetUserName(int userId)
    {
        User? user = _repository.GetById(userId);
        return user?.Name;  // <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Returns null if user is null
    }
}
</pre>
<div style="background: #f8f9fa; padding: 40px; border-radius: 12px; margin: 40px 0; border: 2px solid #4facfe;">
<h4 style="color: #00f2fe; margin-top: 0; font-size: 1.7em; font-weight: 700;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3af.png" alt="🎯" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Nullable Syntax</h4>
<pre class="EnlighterJSRAW" data-enlighter-language="csharp">
// Non-nullable reference type (default)
string name = "Alice";
name = null;  // <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/26a0.png" alt="⚠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Warning: Cannot assign null

// Nullable reference type (explicit ?)
string? name = null;  // <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> OK
name = "Alice";      // <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> OK

// Non-nullable in method signatures
public void ProcessUser(User user)  // user cannot be null
{
    Console.WriteLine(user.Name);  // <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> No null check needed
}

// Nullable in method signatures
public void ProcessUser(User? user)  // user might be null
{
    if (user != null)
    {
        Console.WriteLine(user.Name);  // <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Null checked
    }
}

// Return types
public User GetUser(int id)      // Never returns null
public User? FindUser(int id)    // Might return null
</pre>
</p></div>
<h3 style="color: #2c3e50; font-size: 2.2em; margin: 50px 0 30px 0; font-weight: 700; border-left: 5px solid #667eea; padding-left: 20px;">Null-Handling Patterns</h3>
<pre class="EnlighterJSRAW" data-enlighter-language="csharp">
User? user = FindUser(123);

// 1. Null check
if (user != null)
{
    Console.WriteLine(user.Name);
}

// 2. Null-conditional operator
Console.WriteLine(user?.Name);  // Returns null if user is null

// 3. Null-coalescing operator
string name = user?.Name ?? "Unknown";

// 4. Throw if null
User nonNullUser = user ?? throw new ArgumentNullException(nameof(user));

// 5. Pattern matching
if (user is { Name: var name })
{
    Console.WriteLine(name);  // user is not null here
}

// 6. Null-forgiving operator (! - use sparingly!)
Console.WriteLine(user!.Name);  // Tell compiler: "I know it's not null"
// Use only when you're 100% sure
</pre>
<h3 style="color: #2c3e50; font-size: 2.2em; margin: 50px 0 30px 0; font-weight: 700; border-left: 5px solid #f39c12; padding-left: 20px;">Constructor and Property Initialization</h3>
<pre class="EnlighterJSRAW" data-enlighter-language="csharp">
public class User
{
    // <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/26a0.png" alt="⚠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Warning: Non-nullable property must be initialized
    public string Name { get; set; }
    
    // <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Fixed: Initialize in constructor
    public User(string name)
    {
        Name = name;
    }
}

// Or use required (C# 11)
public class User
{
    public required string Name { get; set; }
    public string? Email { get; set; }  // Optional, can be null
}

var user = new User { Name = "Alice" };  // <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> OK
var user2 = new User { Email = "test@example.com" };  // <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/26a0.png" alt="⚠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Error: Name required

// Or default value
public class User
{
    public string Name { get; set; } = string.Empty;
    public List<Order> Orders { get; set; } = new();
}
</pre>
<div style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 35px; border-radius: 12px; margin: 40px 0;">
<h4 style="margin-top: 0; font-size: 1.7em; font-weight: 700;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f527.png" alt="🔧" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Suppress Warnings (When Needed)</h4>
<pre style="background: rgba(0,0,0,0.3); color: #fff; padding: 25px; border-radius: 8px; font-size: 1.05em; line-height: 1.8;">
// Null-forgiving operator !
string GetName(User? user)
{
    // You KNOW user is not null (e.g., validated earlier)
    return user!.Name;  // Suppresses warning
}

// Pragma directive (suppress for block)
#pragma warning disable CS8600  // Converting null literal
string? name = null;
#pragma warning restore CS8600

// Attribute (for methods that ensure non-null)
public static bool TryGetUser(int id, [NotNullWhen(true)] out User? user)
{
    user = FindUser(id);
    return user != null;
}

if (TryGetUser(123, out var user))
{
    Console.WriteLine(user.Name);  // <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Compiler knows user is not null
}
</pre>
</p></div>
<div style="background: linear-gradient(135deg, #d4edda 0%, #c3e6cb 100%); padding: 35px; border-radius: 12px; margin: 40px 0; border-left: 5px solid #28a745;">
<h4 style="color: #155724; margin-top: 0; font-size: 1.7em; font-weight: 700;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Benefits</h4>
<ul style="color: #155724; font-size: 1.15em; line-height: 2.2; margin: 20px 0;">
<li><strong>Catch bugs early:</strong> At compile-time, not runtime</li>
<li><strong>Self-documenting:</strong> API clearly shows what can be null</li>
<li><strong>Better tooling:</strong> IDE shows nullable warnings</li>
<li><strong>Safer code:</strong> Forces you to handle null cases</li>
<li><strong>Fewer crashes:</strong> NullReferenceException reduced dramatically</li>
</ul></div>
<div style="background: linear-gradient(135deg, #fff3cd 0%, #ffe69c 100%); border-left: 5px solid #ffc107; padding: 35px; margin: 50px 0; border-radius: 12px;">
<h4 style="color: #856404; margin-top: 0; font-size: 1.7em; font-weight: 700;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4a1.png" alt="💡" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Migration Strategy</h4>
<ul style="color: #856404; font-size: 1.15em; line-height: 2.2; margin: 20px 0;">
<li><strong>Enable gradually:</strong> Per-file with #nullable enable</li>
<li><strong>Start with new code:</strong> Don&#8217;t rewrite everything at once</li>
<li><strong>Fix warnings systematically:</strong> Don&#8217;t suppress blindly</li>
<li><strong>Use analyzers:</strong> Enable all nullable warnings</li>
<li><strong>Team buy-in:</strong> Everyone must understand nullable</li>
</ul></div>
<div style="background: #f8f9fa; padding: 40px; border-radius: 12px; margin: 40px 0; border: 2px solid #4facfe;">
<h4 style="color: #00f2fe; margin-top: 0; font-size: 1.7em; font-weight: 700;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3af.png" alt="🎯" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Real-World Example</h4>
<pre class="EnlighterJSRAW" data-enlighter-language="csharp">
#nullable enable

public class OrderService
{
    private readonly IOrderRepository _repository;
    private readonly IEmailService _emailService;

    public OrderService(IOrderRepository repository, IEmailService emailService)
    {
        _repository = repository;
        _emailService = emailService;
    }

    // Clear contract: Never returns null
    public Order GetOrder(int id)
    {
        Order? order = _repository.FindById(id);
        
        if (order == null)
        {
            throw new OrderNotFoundException($"Order {id} not found");
        }
        
        return order;  // <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Guaranteed non-null
    }

    // Clear contract: Might return null
    public Order? FindOrder(int id)
    {
        return _repository.FindById(id);  // <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Nullable return
    }

    public async Task ProcessOrder(Order order, string? promoCode)
    {
        // order is non-nullable - no need to check
        order.Status = OrderStatus.Processing;

        // promoCode is nullable - must check
        if (promoCode != null)
        {
            ApplyPromoCode(order, promoCode);
        }

        await _repository.SaveAsync(order);
        
        // Email might be null, handle gracefully
        await _emailService.SendConfirmationAsync(order.CustomerEmail ?? "no-reply@store.com");
    }
}
</pre>
</p></div>
<blockquote style="background: linear-gradient(to right, #e0f7fa, #b2ebf2); border-left: 6px solid #00bcd4; padding: 40px; margin: 50px 0; border-radius: 12px;">
<p style="font-size: 1.5em; line-height: 1.9; margin: 0; color: #006064; font-style: italic; font-weight: 500;">&#8220;Enabled nullable reference types on legacy codebase. Compiler found 147 potential null bugs. Fixed them all. NullReferenceException crashes dropped 95%. Best decision for code quality.&#8221;</p>
<footer style="margin-top: 20px; color: #00838f; font-size: 1.15em; font-weight: 600;">— Tech Lead</footer>
</blockquote>
]]></content:encoded>
					
					<wfw:commentRss>http://blog.ercanopak.com/c-enable-nullable-reference-types-to-eliminate-null-reference-exceptions/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>C#: Use Record Types for Immutable Data Objects</title>
		<link>http://blog.ercanopak.com/c-use-record-types-for-immutable-data-objects/</link>
					<comments>http://blog.ercanopak.com/c-use-record-types-for-immutable-data-objects/#respond</comments>
		
		<dc:creator><![CDATA[ErcanOPAK]]></dc:creator>
		<pubDate>Mon, 30 Mar 2026 17:52:00 +0000</pubDate>
				<category><![CDATA[C#]]></category>
		<category><![CDATA[C# 9]]></category>
		<category><![CDATA[C# Tips]]></category>
		<category><![CDATA[Data Classes]]></category>
		<category><![CDATA[DTOs]]></category>
		<category><![CDATA[immutability]]></category>
		<category><![CDATA[Modern C#]]></category>
		<category><![CDATA[Pattern Matching]]></category>
		<category><![CDATA[Record Types]]></category>
		<category><![CDATA[Value Objects]]></category>
		<guid isPermaLink="false">http://blog.ercanopak.com/c-use-record-types-for-immutable-data-objects/</guid>

					<description><![CDATA[📦 Value Objects Made Easy DTOs with 50 lines of boilerplate? Equals(), GetHashCode(), ToString()? Record types (C# 9+) are immutable, value-based, with auto-generated methods. One line replaces 50. Traditional Class vs Record // ❌ Traditional class - Lots of boilerplate public class PersonClass { public string Name { get; init; } public int Age { [&#8230;]]]></description>
										<content:encoded><![CDATA[<div style="background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); color: white; padding: 50px 40px; border-radius: 16px; margin: 40px 0; box-shadow: 0 20px 60px rgba(0,0,0,0.3);">
<h2 style="margin: 0 0 20px 0; font-size: 2.8em; font-weight: 800; line-height: 1.2;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4e6.png" alt="📦" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Value Objects Made Easy</h2>
<p style="font-size: 1.4em; line-height: 1.8; margin: 0; opacity: 0.95;">DTOs with 50 lines of boilerplate? Equals(), GetHashCode(), ToString()? <strong>Record types</strong> (C# 9+) are immutable, value-based, with auto-generated methods. One line replaces 50.</p>
</p></div>
<h3 style="color: #2c3e50; font-size: 2.2em; margin: 50px 0 30px 0; font-weight: 700; border-left: 5px solid #f5576c; padding-left: 20px;">Traditional Class vs Record</h3>
<pre class="EnlighterJSRAW" data-enlighter-language="csharp">
// <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/274c.png" alt="❌" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Traditional class - Lots of boilerplate
public class PersonClass
{
    public string Name { get; init; }
    public int Age { get; init; }
    
    public PersonClass(string name, int age)
    {
        Name = name;
        Age = age;
    }
    
    // Manual Equals
    public override bool Equals(object? obj)
    {
        if (obj is not PersonClass other) return false;
        return Name == other.Name && Age == other.Age;
    }
    
    // Manual GetHashCode
    public override int GetHashCode()
    {
        return HashCode.Combine(Name, Age);
    }
    
    // Manual ToString
    public override string ToString()
    {
        return $"PersonClass {{ Name = {Name}, Age = {Age} }}";
    }
    
    // Manual copy with changes
    public PersonClass WithAge(int newAge)
    {
        return new PersonClass(Name, newAge);
    }
}

// 40+ lines for simple data object!

// <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Record - One line!
public record Person(string Name, int Age);

// That's it! Auto-generates:
// - Constructor
// - Properties (init-only)
// - Equals() and GetHashCode() (value-based)
// - ToString()
// - Deconstruct()
// - With expressions
</pre>
<div style="background: #f8f9fa; padding: 40px; border-radius: 12px; margin: 40px 0; border: 2px solid #f093fb;">
<h4 style="color: #f5576c; margin-top: 0; font-size: 1.7em; font-weight: 700;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3af.png" alt="🎯" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Record Features</h4>
<pre class="EnlighterJSRAW" data-enlighter-language="csharp">
public record Person(string Name, int Age);

// Value-based equality
var person1 = new Person("Alice", 30);
var person2 = new Person("Alice", 30);

Console.WriteLine(person1 == person2);  // True! (value equality)
// With classes: False (reference equality)

// Auto ToString()
Console.WriteLine(person1);  // Person { Name = Alice, Age = 30 }

// With expressions (non-destructive mutation)
var person3 = person1 with { Age = 31 };
Console.WriteLine(person3);  // Person { Name = Alice, Age = 31 }
// person1 unchanged (immutable)

// Deconstruction
var (name, age) = person1;
Console.WriteLine($"{name} is {age}");  // Alice is 30

// Pattern matching
var message = person1 switch
{
    { Age: < 18 } => "Minor",
    { Age: >= 18 and < 65 } => "Adult",
    _ => "Senior"
};
</pre>
</p></div>
<h3 style="color: #2c3e50; font-size: 2.2em; margin: 50px 0 30px 0; font-weight: 700; border-left: 5px solid #667eea; padding-left: 20px;">Record vs Record Struct vs Class</h3>
<pre class="EnlighterJSRAW" data-enlighter-language="csharp">
// Record (reference type, immutable by default)
public record Person(string Name, int Age);

// Record struct (value type, C# 10+)
public record struct Point(int X, int Y);

// Class (reference type, mutable)
public class PersonClass
{
    public string Name { get; set; }
    public int Age { get; set; }
}

// When to use what?
// Record: DTOs, value objects, immutable data
// Record struct: Small data (< 16 bytes), high-performance scenarios
// Class: Entities with behavior, mutable state
</pre>
<h3 style="color: #2c3e50; font-size: 2.2em; margin: 50px 0 30px 0; font-weight: 700; border-left: 5px solid #f39c12; padding-left: 20px;">Advanced Record Features</h3>
<pre class="EnlighterJSRAW" data-enlighter-language="csharp">
// Additional properties and methods
public record Person(string Name, int Age)
{
    // Computed property
    public string DisplayName => $"{Name} ({Age})";
    
    // Validation
    public Person
    {
        if (Age < 0) throw new ArgumentException("Age cannot be negative");
    }
    
    // Additional methods
    public bool IsAdult() => Age >= 18;
}

// Inheritance (records can inherit from records)
public record Employee(string Name, int Age, string Department) 
    : Person(Name, Age);

var emp = new Employee("Bob", 25, "IT");
Console.WriteLine(emp);  
// Employee { Name = Bob, Age = 25, Department = IT }

// With expression works with derived records
var emp2 = emp with { Department = "HR" };
</pre>
<div style="background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); color: white; padding: 35px; border-radius: 12px; margin: 40px 0;">
<h4 style="margin-top: 0; font-size: 1.7em; font-weight: 700;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f310.png" alt="🌐" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Perfect for DTOs</h4>
<pre style="background: rgba(0,0,0,0.3); color: #fff; padding: 25px; border-radius: 8px; font-size: 1.05em; line-height: 1.8;">
// API Request/Response DTOs
public record CreateUserRequest(
    string Email,
    string Name,
    string Password
);

public record UserResponse(
    int Id,
    string Email,
    string Name,
    DateTime CreatedAt
);

// API Controller
[HttpPost("users")]
public async Task<UserResponse> CreateUser(CreateUserRequest request)
{
    var user = await _userService.CreateAsync(request);
    return new UserResponse(
        user.Id,
        user.Email,
        user.Name,
        user.CreatedAt
    );
}

// Clean, immutable, perfect for data transfer
</pre>
</p></div>
<h3 style="color: #2c3e50; font-size: 2.2em; margin: 50px 0 30px 0; font-weight: 700; border-left: 5px solid #27ae60; padding-left: 20px;">Positional vs Nominal Records</h3>
<pre class="EnlighterJSRAW" data-enlighter-language="csharp">
// Positional record (concise)
public record Person(string Name, int Age);

// Nominal record (traditional property syntax)
public record Person
{
    public string Name { get; init; }
    public int Age { get; init; }
}

// Mix both
public record Person(string Name, int Age)
{
    public string Email { get; init; } = string.Empty;
    public DateTime CreatedAt { get; init; } = DateTime.UtcNow;
}

var person = new Person("Alice", 30)
{
    Email = "alice@example.com"
};
</pre>
<div style="background: linear-gradient(135deg, #d4edda 0%, #c3e6cb 100%); padding: 35px; border-radius: 12px; margin: 40px 0; border-left: 5px solid #28a745;">
<h4 style="color: #155724; margin-top: 0; font-size: 1.7em; font-weight: 700;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Benefits of Records</h4>
<ul style="color: #155724; font-size: 1.15em; line-height: 2.2; margin: 20px 0;">
<li><strong>Less code:</strong> 90% less boilerplate than classes</li>
<li><strong>Immutable by default:</strong> Thread-safe, predictable</li>
<li><strong>Value semantics:</strong> Equality based on data, not reference</li>
<li><strong>With expressions:</strong> Easy non-destructive updates</li>
<li><strong>Pattern matching:</strong> Works beautifully with switch</li>
<li><strong>Auto ToString():</strong> Great for debugging</li>
</ul></div>
<div style="background: linear-gradient(135deg, #fff3cd 0%, #ffe69c 100%); border-left: 5px solid #ffc107; padding: 35px; margin: 50px 0; border-radius: 12px;">
<h4 style="color: #856404; margin-top: 0; font-size: 1.7em; font-weight: 700;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4a1.png" alt="💡" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Best Practices</h4>
<ul style="color: #856404; font-size: 1.15em; line-height: 2.2; margin: 20px 0;">
<li><strong>Use for DTOs:</strong> API requests/responses, messages</li>
<li><strong>Use for value objects:</strong> Money, Address, Coordinate</li>
<li><strong>Add validation:</strong> In constructor or properties</li>
<li><strong>Keep immutable:</strong> Use init, not set</li>
<li><strong>Prefer positional:</strong> More concise for simple records</li>
</ul></div>
<div style="background: #f8f9fa; padding: 40px; border-radius: 12px; margin: 40px 0; border: 2px solid #f093fb;">
<h4 style="color: #f5576c; margin-top: 0; font-size: 1.7em; font-weight: 700;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3af.png" alt="🎯" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Real-World Example</h4>
<pre class="EnlighterJSRAW" data-enlighter-language="csharp">
// Domain value objects
public record Money(decimal Amount, string Currency)
{
    public Money Add(Money other)
    {
        if (Currency != other.Currency)
            throw new InvalidOperationException("Currency mismatch");
        return this with { Amount = Amount + other.Amount };
    }
}

public record Address(
    string Street,
    string City,
    string State,
    string ZipCode,
    string Country
);

public record CustomerDto(
    int Id,
    string Name,
    Address Address,
    Money Balance
);

// Usage
var addr = new Address("123 Main St", "NYC", "NY", "10001", "USA");
var balance = new Money(1000m, "USD");
var customer = new CustomerDto(1, "Alice", addr, balance);

// Update address
var updated = customer with 
{ 
    Address = customer.Address with { City = "Boston" }
};

// Value equality
var addr2 = new Address("123 Main St", "NYC", "NY", "10001", "USA");
Console.WriteLine(addr == addr2);  // True!
</pre>
</p></div>
<blockquote style="background: linear-gradient(to right, #fce4ec, #f8bbd0); border-left: 6px solid #e91e63; padding: 40px; margin: 50px 0; border-radius: 12px;">
<p style="font-size: 1.5em; line-height: 1.9; margin: 0; color: #880e4f; font-style: italic; font-weight: 500;">"Converted all DTOs from classes to records. Deleted 2000+ lines of boilerplate. Bugs related to mutable state disappeared. API responses now immutable, thread-safe. Should've used records from day one."</p>
<footer style="margin-top: 20px; color: #ad1457; font-size: 1.15em; font-weight: 600;">— .NET Developer</footer>
</blockquote>
]]></content:encoded>
					
					<wfw:commentRss>http://blog.ercanopak.com/c-use-record-types-for-immutable-data-objects/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>SQL: Use CTEs for Readable Complex Queries</title>
		<link>http://blog.ercanopak.com/sql-use-ctes-for-readable-complex-queries-2/</link>
					<comments>http://blog.ercanopak.com/sql-use-ctes-for-readable-complex-queries-2/#respond</comments>
		
		<dc:creator><![CDATA[ErcanOPAK]]></dc:creator>
		<pubDate>Mon, 30 Mar 2026 17:51:53 +0000</pubDate>
				<category><![CDATA[SQL]]></category>
		<category><![CDATA[Advanced SQL]]></category>
		<category><![CDATA[Common Table Expressions]]></category>
		<category><![CDATA[cte]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[Query Readability]]></category>
		<category><![CDATA[Recursive CTE]]></category>
		<category><![CDATA[SQL Best Practices]]></category>
		<category><![CDATA[SQL Tips]]></category>
		<category><![CDATA[WITH Clause]]></category>
		<guid isPermaLink="false">http://blog.ercanopak.com/sql-use-ctes-for-readable-complex-queries-2/</guid>

					<description><![CDATA[📝 Named Subqueries Nested subqueries everywhere? Can&#8217;t understand your own query? CTEs (WITH clause) create temporary named result sets. Makes complex queries readable. The Subquery Nightmare -- ❌ Nested subqueries - Unreadable! SELECT customer_name, total_orders, avg_order_value FROM ( SELECT c.name AS customer_name, COUNT(o.id) AS total_orders, AVG(o.total) AS avg_order_value FROM customers c JOIN ( SELECT * [&#8230;]]]></description>
										<content:encoded><![CDATA[<div style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 50px 40px; border-radius: 16px; margin: 40px 0; box-shadow: 0 20px 60px rgba(0,0,0,0.3);">
<h2 style="margin: 0 0 20px 0; font-size: 2.8em; font-weight: 800; line-height: 1.2;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4dd.png" alt="📝" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Named Subqueries</h2>
<p style="font-size: 1.4em; line-height: 1.8; margin: 0; opacity: 0.95;">Nested subqueries everywhere? Can&#8217;t understand your own query? <strong>CTEs (WITH clause)</strong> create temporary named result sets. Makes complex queries readable.</p>
</p></div>
<h3 style="color: #2c3e50; font-size: 2.2em; margin: 50px 0 30px 0; font-weight: 700; border-left: 5px solid #764ba2; padding-left: 20px;">The Subquery Nightmare</h3>
<pre class="EnlighterJSRAW" data-enlighter-language="sql">
-- <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/274c.png" alt="❌" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Nested subqueries - Unreadable!
SELECT 
  customer_name,
  total_orders,
  avg_order_value
FROM (
  SELECT 
    c.name AS customer_name,
    COUNT(o.id) AS total_orders,
    AVG(o.total) AS avg_order_value
  FROM customers c
  JOIN (
    SELECT * 
    FROM orders 
    WHERE status = 'completed'
  ) o ON c.id = o.customer_id
  WHERE c.created_at > '2024-01-01'
  GROUP BY c.id, c.name
) customer_stats
WHERE total_orders > 5
ORDER BY avg_order_value DESC;

-- Hard to read, maintain, debug
</pre>
<h3 style="color: #2c3e50; font-size: 2.2em; margin: 50px 0 30px 0; font-weight: 700; border-left: 5px solid #27ae60; padding-left: 20px;">CTE Solution &#8211; Clean &#038; Readable</h3>
<pre class="EnlighterJSRAW" data-enlighter-language="sql">
-- <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> CTE - Step by step, readable
WITH completed_orders AS (
  SELECT * 
  FROM orders 
  WHERE status = 'completed'
),
recent_customers AS (
  SELECT * 
  FROM customers 
  WHERE created_at > '2024-01-01'
),
customer_stats AS (
  SELECT 
    c.id,
    c.name AS customer_name,
    COUNT(o.id) AS total_orders,
    AVG(o.total) AS avg_order_value
  FROM recent_customers c
  JOIN completed_orders o ON c.id = o.customer_id
  GROUP BY c.id, c.name
)
SELECT 
  customer_name,
  total_orders,
  avg_order_value
FROM customer_stats
WHERE total_orders > 5
ORDER BY avg_order_value DESC;

-- Each step has a name!
-- Easy to understand flow
-- Easy to debug each CTE separately
</pre>
<div style="background: #f8f9fa; padding: 40px; border-radius: 12px; margin: 40px 0; border: 2px solid #667eea;">
<h4 style="color: #667eea; margin-top: 0; font-size: 1.7em; font-weight: 700;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3af.png" alt="🎯" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Multiple CTEs</h4>
<pre class="EnlighterJSRAW" data-enlighter-language="sql">
-- Define multiple CTEs with comma separation
WITH 
-- CTE 1: Sales by product
product_sales AS (
  SELECT 
    product_id,
    SUM(quantity) AS total_quantity,
    SUM(total_price) AS total_revenue
  FROM order_items
  WHERE order_date >= '2024-01-01'
  GROUP BY product_id
),
-- CTE 2: Top products
top_products AS (
  SELECT 
    product_id,
    total_revenue
  FROM product_sales
  WHERE total_revenue > 10000
),
-- CTE 3: Product details
product_details AS (
  SELECT 
    p.id,
    p.name,
    p.category,
    tp.total_revenue
  FROM products p
  JOIN top_products tp ON p.id = tp.product_id
)
-- Final query uses all CTEs
SELECT 
  category,
  COUNT(*) AS product_count,
  SUM(total_revenue) AS category_revenue
FROM product_details
GROUP BY category
ORDER BY category_revenue DESC;
</pre>
</p></div>
<h3 style="color: #2c3e50; font-size: 2.2em; margin: 50px 0 30px 0; font-weight: 700; border-left: 5px solid #f39c12; padding-left: 20px;">Recursive CTEs</h3>
<pre class="EnlighterJSRAW" data-enlighter-language="sql">
-- Hierarchical data: Employee org chart
WITH RECURSIVE employee_hierarchy AS (
  -- Base case: Top-level managers (no manager)
  SELECT 
    id,
    name,
    manager_id,
    1 AS level,
    name AS path
  FROM employees
  WHERE manager_id IS NULL
  
  UNION ALL
  
  -- Recursive case: Employees with managers
  SELECT 
    e.id,
    e.name,
    e.manager_id,
    eh.level + 1,
    eh.path || ' > ' || e.name
  FROM employees e
  JOIN employee_hierarchy eh ON e.manager_id = eh.id
)
SELECT 
  id,
  name,
  level,
  path
FROM employee_hierarchy
ORDER BY level, name;

-- Result:
-- id | name    | level | path
-- 1  | CEO     | 1     | CEO
-- 2  | CTO     | 2     | CEO > CTO
-- 3  | CFO     | 2     | CEO > CFO
-- 4  | Dev1    | 3     | CEO > CTO > Dev1
-- 5  | Dev2    | 3     | CEO > CTO > Dev2
</pre>
<div style="background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); color: white; padding: 35px; border-radius: 12px; margin: 40px 0;">
<h4 style="margin-top: 0; font-size: 1.7em; font-weight: 700;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f504.png" alt="🔄" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Generate Number Series</h4>
<pre style="background: rgba(0,0,0,0.3); color: #fff; padding: 25px; border-radius: 8px; font-size: 1.05em; line-height: 1.8;">
-- Generate numbers 1 to 100
WITH RECURSIVE numbers AS (
  SELECT 1 AS n
  UNION ALL
  SELECT n + 1
  FROM numbers
  WHERE n < 100
)
SELECT n FROM numbers;

-- Generate date range
WITH RECURSIVE date_range AS (
  SELECT DATE('2024-01-01') AS date
  UNION ALL
  SELECT DATE(date, '+1 day')
  FROM date_range
  WHERE date < '2024-12-31'
)
SELECT date FROM date_range;

-- Use case: Fill gaps in data
WITH RECURSIVE all_months AS (
  SELECT DATE('2024-01-01') AS month
  UNION ALL
  SELECT DATE(month, '+1 month')
  FROM all_months
  WHERE month < '2024-12-01'
)
SELECT 
  am.month,
  COALESCE(s.revenue, 0) AS revenue
FROM all_months am
LEFT JOIN monthly_sales s ON am.month = s.month;
</pre>
</p></div>
<h3 style="color: #2c3e50; font-size: 2.2em; margin: 50px 0 30px 0; font-weight: 700; border-left: 5px solid #667eea; padding-left: 20px;">Real-World Examples</h3>
<div style="background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); color: white; padding: 35px; border-radius: 12px; margin: 40px 0;">
<h4 style="margin-top: 0; font-size: 1.7em; font-weight: 700;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4ca.png" alt="📊" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Dashboard Query</h4>
<pre style="background: rgba(0,0,0,0.3); color: #fff; padding: 25px; border-radius: 8px; font-size: 1.05em; line-height: 1.8;">
WITH 
-- Today's sales
today_sales AS (
  SELECT SUM(total) AS today_total
  FROM orders
  WHERE DATE(created_at) = CURRENT_DATE
),
-- Yesterday's sales
yesterday_sales AS (
  SELECT SUM(total) AS yesterday_total
  FROM orders
  WHERE DATE(created_at) = CURRENT_DATE - INTERVAL '1 day'
),
-- This month's sales
month_sales AS (
  SELECT SUM(total) AS month_total
  FROM orders
  WHERE DATE_TRUNC('month', created_at) = DATE_TRUNC('month', CURRENT_DATE)
),
-- Active users today
active_users AS (
  SELECT COUNT(DISTINCT user_id) AS active_count
  FROM user_sessions
  WHERE DATE(created_at) = CURRENT_DATE
)
-- Combine all metrics
SELECT 
  ts.today_total,
  ys.yesterday_total,
  ts.today_total - ys.yesterday_total AS daily_change,
  ms.month_total,
  au.active_count
FROM today_sales ts, yesterday_sales ys, month_sales ms, active_users au;
</pre>
</p></div>
<div style="background: linear-gradient(135deg, #d4edda 0%, #c3e6cb 100%); padding: 35px; border-radius: 12px; margin: 40px 0; border-left: 5px solid #28a745;">
<h4 style="color: #155724; margin-top: 0; font-size: 1.7em; font-weight: 700;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Benefits of CTEs</h4>
<ul style="color: #155724; font-size: 1.15em; line-height: 2.2; margin: 20px 0;">
<li><strong>Readability:</strong> Named steps are self-documenting</li>
<li><strong>Maintainability:</strong> Easy to modify individual steps</li>
<li><strong>Debugging:</strong> Test each CTE separately</li>
<li><strong>Reusability:</strong> Reference same CTE multiple times</li>
<li><strong>Recursion:</strong> Handle hierarchical data</li>
</ul></div>
<div style="background: linear-gradient(135deg, #fff3cd 0%, #ffe69c 100%); border-left: 5px solid #ffc107; padding: 35px; margin: 50px 0; border-radius: 12px;">
<h4 style="color: #856404; margin-top: 0; font-size: 1.7em; font-weight: 700;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4a1.png" alt="💡" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Pro Tips</h4>
<ul style="color: #856404; font-size: 1.15em; line-height: 2.2; margin: 20px 0;">
<li><strong>Name meaningfully:</strong> recent_customers, not temp1</li>
<li><strong>One CTE per logical step:</strong> Don't try to do everything in one</li>
<li><strong>Debug incrementally:</strong> Run each CTE separately first</li>
<li><strong>Consider performance:</strong> CTEs not always faster than subqueries</li>
<li><strong>Use for recursion:</strong> Perfect for trees, graphs</li>
</ul></div>
<blockquote style="background: linear-gradient(to right, #e8eaf6, #c5cae9); border-left: 6px solid #5c6bc0; padding: 40px; margin: 50px 0; border-radius: 12px;">
<p style="font-size: 1.5em; line-height: 1.9; margin: 0; color: #1a237e; font-style: italic; font-weight: 500;">"Inherited 200-line query with 7 levels of nested subqueries. Couldn't understand it. Rewrote with CTEs. Now 15 named steps, crystal clear. Junior dev understood it immediately."</p>
<footer style="margin-top: 20px; color: #283593; font-size: 1.15em; font-weight: 600;">— Database Developer</footer>
</blockquote>
]]></content:encoded>
					
					<wfw:commentRss>http://blog.ercanopak.com/sql-use-ctes-for-readable-complex-queries-2/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>SQL: Use Window Functions for Advanced Analytical Queries</title>
		<link>http://blog.ercanopak.com/sql-use-window-functions-for-advanced-analytical-queries/</link>
					<comments>http://blog.ercanopak.com/sql-use-window-functions-for-advanced-analytical-queries/#respond</comments>
		
		<dc:creator><![CDATA[ErcanOPAK]]></dc:creator>
		<pubDate>Mon, 30 Mar 2026 17:51:47 +0000</pubDate>
				<category><![CDATA[SQL]]></category>
		<category><![CDATA[Advanced SQL]]></category>
		<category><![CDATA[analytics]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[Query Optimization]]></category>
		<category><![CDATA[RANK]]></category>
		<category><![CDATA[row_number]]></category>
		<category><![CDATA[sql server]]></category>
		<category><![CDATA[SQL Tips]]></category>
		<category><![CDATA[Window Functions]]></category>
		<guid isPermaLink="false">http://blog.ercanopak.com/sql-use-window-functions-for-advanced-analytical-queries/</guid>

					<description><![CDATA[📊 SQL Superpowers Need row numbers? Running totals? Rankings? Window functions perform calculations across table rows without GROUP BY. Game-changing for analytics. ROW_NUMBER() &#8211; Assign Row Numbers -- ❌ Old way: Can't number rows easily SELECT name, salary, department FROM employees ORDER BY salary DESC; -- ✅ Window function: Add row numbers SELECT ROW_NUMBER() OVER [&#8230;]]]></description>
										<content:encoded><![CDATA[<div style="background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); color: white; padding: 50px 40px; border-radius: 16px; margin: 40px 0; box-shadow: 0 20px 60px rgba(0,0,0,0.3);">
<h2 style="margin: 0 0 20px 0; font-size: 2.8em; font-weight: 800; line-height: 1.2;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4ca.png" alt="📊" class="wp-smiley" style="height: 1em; max-height: 1em;" /> SQL Superpowers</h2>
<p style="font-size: 1.4em; line-height: 1.8; margin: 0; opacity: 0.95;">Need row numbers? Running totals? Rankings? <strong>Window functions</strong> perform calculations across table rows without GROUP BY. Game-changing for analytics.</p>
</p></div>
<h3 style="color: #2c3e50; font-size: 2.2em; margin: 50px 0 30px 0; font-weight: 700; border-left: 5px solid #00f2fe; padding-left: 20px;">ROW_NUMBER() &#8211; Assign Row Numbers</h3>
<pre class="EnlighterJSRAW" data-enlighter-language="sql">
-- <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/274c.png" alt="❌" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Old way: Can't number rows easily
SELECT name, salary, department
FROM employees
ORDER BY salary DESC;

-- <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Window function: Add row numbers
SELECT 
  ROW_NUMBER() OVER (ORDER BY salary DESC) AS row_num,
  name,
  salary,
  department
FROM employees;

-- Result:
-- row_num | name    | salary | department
-- 1       | Alice   | 120000 | Engineering
-- 2       | Bob     | 110000 | Engineering
-- 3       | Charlie | 100000 | Sales
-- 4       | David   | 95000  | Marketing

-- Row number per department
SELECT 
  ROW_NUMBER() OVER (PARTITION BY department ORDER BY salary DESC) AS dept_rank,
  name,
  salary,
  department
FROM employees;

-- Result: Separate numbering per department
-- dept_rank | name    | salary | department
-- 1         | Alice   | 120000 | Engineering
-- 2         | Bob     | 110000 | Engineering
-- 1         | Charlie | 100000 | Sales
-- 1         | David   | 95000  | Marketing
</pre>
<div style="background: #f8f9fa; padding: 40px; border-radius: 12px; margin: 40px 0; border: 2px solid #4facfe;">
<h4 style="color: #00f2fe; margin-top: 0; font-size: 1.7em; font-weight: 700;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4c8.png" alt="📈" class="wp-smiley" style="height: 1em; max-height: 1em;" /> RANK() and DENSE_RANK()</h4>
<pre class="EnlighterJSRAW" data-enlighter-language="sql">
-- RANK() - Gaps in ranking for ties
SELECT 
  RANK() OVER (ORDER BY score DESC) AS rank,
  name,
  score
FROM students;

-- score: 100, 100, 95, 90
-- rank:  1,   1,   3,  4  (gap at 2!)

-- DENSE_RANK() - No gaps
SELECT 
  DENSE_RANK() OVER (ORDER BY score DESC) AS rank,
  name,
  score
FROM students;

-- score: 100, 100, 95, 90
-- rank:  1,   1,   2,  3  (no gap)

-- Top 3 salaries per department
SELECT *
FROM (
  SELECT 
    name,
    salary,
    department,
    RANK() OVER (PARTITION BY department ORDER BY salary DESC) AS dept_rank
  FROM employees
) ranked
WHERE dept_rank <= 3;
</pre>
</p></div>
<h3 style="color: #2c3e50; font-size: 2.2em; margin: 50px 0 30px 0; font-weight: 700; border-left: 5px solid #667eea; padding-left: 20px;">Running Totals with SUM()</h3>
<pre class="EnlighterJSRAW" data-enlighter-language="sql">
-- Running total of sales
SELECT 
  order_date,
  amount,
  SUM(amount) OVER (ORDER BY order_date) AS running_total
FROM orders;

-- Result:
-- order_date | amount | running_total
-- 2024-01-01 | 100    | 100
-- 2024-01-02 | 150    | 250  (100 + 150)
-- 2024-01-03 | 200    | 450  (100 + 150 + 200)

-- Running total per customer
SELECT 
  customer_id,
  order_date,
  amount,
  SUM(amount) OVER (
    PARTITION BY customer_id 
    ORDER BY order_date
  ) AS customer_running_total
FROM orders;

-- Separate running total for each customer
</pre>
<h3 style="color: #2c3e50; font-size: 2.2em; margin: 50px 0 30px 0; font-weight: 700; border-left: 5px solid #f39c12; padding-left: 20px;">LAG() and LEAD() - Previous/Next Row</h3>
<pre class="EnlighterJSRAW" data-enlighter-language="sql">
-- Compare with previous day
SELECT 
  order_date,
  revenue,
  LAG(revenue) OVER (ORDER BY order_date) AS prev_day_revenue,
  revenue - LAG(revenue) OVER (ORDER BY order_date) AS daily_change
FROM daily_revenue;

-- Result:
-- order_date | revenue | prev_day_revenue | daily_change
-- 2024-01-01 | 1000    | NULL             | NULL
-- 2024-01-02 | 1200    | 1000             | 200
-- 2024-01-03 | 950     | 1200             | -250

-- LEAD() for next row
SELECT 
  order_date,
  revenue,
  LEAD(revenue) OVER (ORDER BY order_date) AS next_day_revenue
FROM daily_revenue;

-- LAG with offset (2 days ago)
SELECT 
  order_date,
  revenue,
  LAG(revenue, 2) OVER (ORDER BY order_date) AS two_days_ago
FROM daily_revenue;
</pre>
<div style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 35px; border-radius: 12px; margin: 40px 0;">
<h4 style="margin-top: 0; font-size: 1.7em; font-weight: 700;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3af.png" alt="🎯" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Moving Averages</h4>
<pre style="background: rgba(0,0,0,0.3); color: #fff; padding: 25px; border-radius: 8px; font-size: 1.05em; line-height: 1.8;">
-- 7-day moving average
SELECT 
  order_date,
  revenue,
  AVG(revenue) OVER (
    ORDER BY order_date
    ROWS BETWEEN 6 PRECEDING AND CURRENT ROW
  ) AS moving_avg_7day
FROM daily_revenue;

-- 3-month moving average
SELECT 
  month,
  total_sales,
  AVG(total_sales) OVER (
    ORDER BY month
    ROWS BETWEEN 2 PRECEDING AND CURRENT ROW
  ) AS moving_avg_3month
FROM monthly_sales;
</pre>
</p></div>
<h3 style="color: #2c3e50; font-size: 2.2em; margin: 50px 0 30px 0; font-weight: 700; border-left: 5px solid #27ae60; padding-left: 20px;">NTILE() - Divide into Buckets</h3>
<pre class="EnlighterJSRAW" data-enlighter-language="sql">
-- Divide customers into 4 quartiles by spend
SELECT 
  customer_id,
  total_spend,
  NTILE(4) OVER (ORDER BY total_spend DESC) AS quartile
FROM customer_totals;

-- Result:
-- customer_id | total_spend | quartile
-- 101         | 50000       | 1  (top 25%)
-- 102         | 48000       | 1
-- 103         | 30000       | 2
-- 104         | 28000       | 2
-- 105         | 15000       | 3
-- 106         | 12000       | 3
-- 107         | 5000        | 4  (bottom 25%)
-- 108         | 3000        | 4

-- Use case: Segment customers
SELECT quartile, COUNT(*) as customer_count
FROM (
  SELECT NTILE(4) OVER (ORDER BY total_spend DESC) AS quartile
  FROM customer_totals
) quartiles
GROUP BY quartile;
</pre>
<div style="background: linear-gradient(135deg, #d4edda 0%, #c3e6cb 100%); padding: 35px; border-radius: 12px; margin: 40px 0; border-left: 5px solid #28a745;">
<h4 style="color: #155724; margin-top: 0; font-size: 1.7em; font-weight: 700;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Real-World Examples</h4>
<h5 style="color: #27ae60; font-size: 1.3em; margin: 20px 0 10px 0;">Pagination</h5>
<pre class="EnlighterJSRAW" data-enlighter-language="sql">
-- Page 2, 10 items per page
SELECT *
FROM (
  SELECT 
    ROW_NUMBER() OVER (ORDER BY created_at DESC) AS row_num,
    *
  FROM posts
) numbered
WHERE row_num BETWEEN 11 AND 20;
</pre>
<h5 style="color: #27ae60; font-size: 1.3em; margin: 20px 0 10px 0;">Top N Per Group</h5>
<pre class="EnlighterJSRAW" data-enlighter-language="sql">
-- Top 5 products per category by sales
SELECT category, product_name, total_sales
FROM (
  SELECT 
    category,
    product_name,
    total_sales,
    ROW_NUMBER() OVER (
      PARTITION BY category 
      ORDER BY total_sales DESC
    ) AS rank
  FROM product_sales
) ranked
WHERE rank <= 5;
</pre>
<h5 style="color: #27ae60; font-size: 1.3em; margin: 20px 0 10px 0;">Percentage of Total</h5>
<pre class="EnlighterJSRAW" data-enlighter-language="sql">
SELECT 
  product,
  sales,
  sales * 100.0 / SUM(sales) OVER () AS pct_of_total
FROM product_sales;

-- Result:
-- product | sales | pct_of_total
-- A       | 5000  | 50.0
-- B       | 3000  | 30.0
-- C       | 2000  | 20.0
</pre>
</p></div>
<div style="background: linear-gradient(135deg, #fff3cd 0%, #ffe69c 100%); border-left: 5px solid #ffc107; padding: 35px; margin: 50px 0; border-radius: 12px;">
<h4 style="color: #856404; margin-top: 0; font-size: 1.7em; font-weight: 700;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4a1.png" alt="💡" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Window Function Syntax</h4>
<pre class="EnlighterJSRAW" data-enlighter-language="sql">
<function> OVER (
  [PARTITION BY column]   -- Optional: Group by
  [ORDER BY column]       -- Optional: Sort order
  [ROWS/RANGE clause]     -- Optional: Frame specification
)

-- Common functions:
-- ROW_NUMBER(), RANK(), DENSE_RANK()
-- SUM(), AVG(), MIN(), MAX(), COUNT()
-- LAG(), LEAD()
-- FIRST_VALUE(), LAST_VALUE()
-- NTILE()
</pre>
</p></div>
<blockquote style="background: linear-gradient(to right, #e0f7fa, #b2ebf2); border-left: 6px solid #00bcd4; padding: 40px; margin: 50px 0; border-radius: 12px;">
<p style="font-size: 1.5em; line-height: 1.9; margin: 0; color: #006064; font-style: italic; font-weight: 500;">"Dashboard needed top 10 products per category. Was using subqueries and JOINs. Switched to window functions with ROW_NUMBER(). Query went from 2 seconds to 0.1 seconds. Code so much cleaner."</p>
<footer style="margin-top: 20px; color: #00838f; font-size: 1.15em; font-weight: 600;">— Data Analyst</footer>
</blockquote>
]]></content:encoded>
					
					<wfw:commentRss>http://blog.ercanopak.com/sql-use-window-functions-for-advanced-analytical-queries/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>.NET Core: Use Background Services for Long-Running Tasks</title>
		<link>http://blog.ercanopak.com/net-core-use-background-services-for-long-running-tasks/</link>
					<comments>http://blog.ercanopak.com/net-core-use-background-services-for-long-running-tasks/#respond</comments>
		
		<dc:creator><![CDATA[ErcanOPAK]]></dc:creator>
		<pubDate>Mon, 30 Mar 2026 17:51:40 +0000</pubDate>
				<category><![CDATA[Asp.Net Core]]></category>
		<category><![CDATA[.Net Core]]></category>
		<category><![CDATA[.NET Tips]]></category>
		<category><![CDATA[ASP.NET Core]]></category>
		<category><![CDATA[background jobs]]></category>
		<category><![CDATA[Background Services]]></category>
		<category><![CDATA[Hosted Services]]></category>
		<category><![CDATA[IHostedService]]></category>
		<category><![CDATA[Long Running Tasks]]></category>
		<category><![CDATA[Scheduled Tasks]]></category>
		<category><![CDATA[Worker Service]]></category>
		<guid isPermaLink="false">http://blog.ercanopak.com/net-core-use-background-services-for-long-running-tasks/</guid>

					<description><![CDATA[⏰ Tasks That Run Forever Need to process queue every minute? Send emails in background? Background Services run continuously alongside your ASP.NET app. Perfect for scheduled tasks, workers. Create Background Service public class EmailProcessorService : BackgroundService { private readonly ILogger _logger; private readonly IServiceProvider _serviceProvider; public EmailProcessorService( ILogger logger, IServiceProvider serviceProvider) { _logger = logger; [&#8230;]]]></description>
										<content:encoded><![CDATA[<div style="background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); color: white; padding: 50px 40px; border-radius: 16px; margin: 40px 0; box-shadow: 0 20px 60px rgba(0,0,0,0.3);">
<h2 style="margin: 0 0 20px 0; font-size: 2.8em; font-weight: 800; line-height: 1.2;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/23f0.png" alt="⏰" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Tasks That Run Forever</h2>
<p style="font-size: 1.4em; line-height: 1.8; margin: 0; opacity: 0.95;">Need to process queue every minute? Send emails in background? <strong>Background Services</strong> run continuously alongside your ASP.NET app. Perfect for scheduled tasks, workers.</p>
</p></div>
<h3 style="color: #2c3e50; font-size: 2.2em; margin: 50px 0 30px 0; font-weight: 700; border-left: 5px solid #f5576c; padding-left: 20px;">Create Background Service</h3>
<pre class="EnlighterJSRAW" data-enlighter-language="csharp">
public class EmailProcessorService : BackgroundService
{
    private readonly ILogger<EmailProcessorService> _logger;
    private readonly IServiceProvider _serviceProvider;

    public EmailProcessorService(
        ILogger<EmailProcessorService> logger,
        IServiceProvider serviceProvider)
    {
        _logger = logger;
        _serviceProvider = serviceProvider;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        _logger.LogInformation("Email Processor Service started");

        while (!stoppingToken.IsCancellationRequested)
        {
            try
            {
                // Create scope for scoped services
                using var scope = _serviceProvider.CreateScope();
                var emailService = scope.ServiceProvider.GetRequiredService<IEmailService>();

                // Process pending emails
                await emailService.ProcessPendingEmailsAsync();

                _logger.LogInformation("Processed emails at {Time}", DateTime.UtcNow);

                // Wait 1 minute before next run
                await Task.Delay(TimeSpan.FromMinutes(1), stoppingToken);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error processing emails");
                await Task.Delay(TimeSpan.FromSeconds(30), stoppingToken);
            }
        }

        _logger.LogInformation("Email Processor Service stopped");
    }
}

// Register in Program.cs
builder.Services.AddHostedService<EmailProcessorService>();
</pre>
<div style="background: #f8f9fa; padding: 40px; border-radius: 12px; margin: 40px 0; border: 2px solid #f093fb;">
<h4 style="color: #f5576c; margin-top: 0; font-size: 1.7em; font-weight: 700;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3af.png" alt="🎯" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Timed Background Service</h4>
<pre class="EnlighterJSRAW" data-enlighter-language="csharp">
public class CleanupService : BackgroundService
{
    private readonly ILogger<CleanupService> _logger;
    private readonly IServiceProvider _serviceProvider;
    private Timer? _timer;

    public CleanupService(
        ILogger<CleanupService> logger,
        IServiceProvider serviceProvider)
    {
        _logger = logger;
        _serviceProvider = serviceProvider;
    }

    protected override Task ExecuteAsync(CancellationToken stoppingToken)
    {
        _logger.LogInformation("Cleanup Service started");

        // Run every hour
        _timer = new Timer(
            DoWork,
            null,
            TimeSpan.Zero,  // Start immediately
            TimeSpan.FromHours(1));  // Run every hour

        return Task.CompletedTask;
    }

    private async void DoWork(object? state)
    {
        _logger.LogInformation("Cleanup running at {Time}", DateTime.UtcNow);

        try
        {
            using var scope = _serviceProvider.CreateScope();
            var dbContext = scope.ServiceProvider.GetRequiredService<AppDbContext>();

            // Delete old records
            var cutoffDate = DateTime.UtcNow.AddDays(-30);
            var oldRecords = await dbContext.Logs
                .Where(l => l.CreatedAt < cutoffDate)
                .ToListAsync();

            dbContext.Logs.RemoveRange(oldRecords);
            await dbContext.SaveChangesAsync();

            _logger.LogInformation("Deleted {Count} old records", oldRecords.Count);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error during cleanup");
        }
    }

    public override Task StopAsync(CancellationToken cancellationToken)
    {
        _timer?.Change(Timeout.Infinite, 0);
        _logger.LogInformation("Cleanup Service stopped");
        return base.StopAsync(cancellationToken);
    }

    public override void Dispose()
    {
        _timer?.Dispose();
        base.Dispose();
    }
}
</pre>
</p></div>
<h3 style="color: #2c3e50; font-size: 2.2em; margin: 50px 0 30px 0; font-weight: 700; border-left: 5px solid #667eea; padding-left: 20px;">Queue Processing Service</h3>
<pre class="EnlighterJSRAW" data-enlighter-language="csharp">
public class OrderProcessingService : BackgroundService
{
    private readonly ILogger<OrderProcessingService> _logger;
    private readonly IServiceProvider _serviceProvider;

    public OrderProcessingService(
        ILogger<OrderProcessingService> logger,
        IServiceProvider serviceProvider)
    {
        _logger = logger;
        _serviceProvider = serviceProvider;
    }

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            try
            {
                using var scope = _serviceProvider.CreateScope();
                var orderQueue = scope.ServiceProvider.GetRequiredService<IOrderQueue>();
                var orderService = scope.ServiceProvider.GetRequiredService<IOrderService>();

                // Dequeue and process orders
                var order = await orderQueue.DequeueAsync(stoppingToken);

                if (order != null)
                {
                    _logger.LogInformation("Processing order {OrderId}", order.Id);

                    await orderService.ProcessAsync(order);
                    await orderQueue.CompleteAsync(order.Id);

                    _logger.LogInformation("Order {OrderId} processed", order.Id);
                }
                else
                {
                    // No orders in queue, wait a bit
                    await Task.Delay(TimeSpan.FromSeconds(5), stoppingToken);
                }
            }
            catch (OperationCanceledException)
            {
                // Expected when stopping
                break;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Error processing order");
                await Task.Delay(TimeSpan.FromSeconds(10), stoppingToken);
            }
        }
    }
}
</pre>
<div style="background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); color: white; padding: 35px; border-radius: 12px; margin: 40px 0;">
<h4 style="margin-top: 0; font-size: 1.7em; font-weight: 700;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4ca.png" alt="📊" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Health Check Integration</h4>
<pre style="background: rgba(0,0,0,0.3); color: #fff; padding: 25px; border-radius: 8px; font-size: 1.05em; line-height: 1.8;">
public class MonitoringService : BackgroundService
{
    private readonly ILogger<MonitoringService> _logger;
    private DateTime _lastRunTime = DateTime.MinValue;
    public bool IsHealthy { get; private set; } = true;

    protected override async Task ExecuteAsync(CancellationToken stoppingToken)
    {
        while (!stoppingToken.IsCancellationRequested)
        {
            try
            {
                // Do monitoring work
                await MonitorSystemAsync();

                _lastRunTime = DateTime.UtcNow;
                IsHealthy = true;

                await Task.Delay(TimeSpan.FromMinutes(5), stoppingToken);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "Monitoring failed");
                IsHealthy = false;
            }
        }
    }

    private async Task MonitorSystemAsync()
    {
        // Check system health
        _logger.LogInformation("System healthy at {Time}", DateTime.UtcNow);
    }
}

// Health check
public class BackgroundServiceHealthCheck : IHealthCheck
{
    private readonly MonitoringService _monitoringService;

    public BackgroundServiceHealthCheck(MonitoringService monitoringService)
    {
        _monitoringService = monitoringService;
    }

    public Task<HealthCheckResult> CheckHealthAsync(
        HealthCheckContext context,
        CancellationToken cancellationToken = default)
    {
        if (_monitoringService.IsHealthy)
        {
            return Task.FromResult(HealthCheckResult.Healthy("Monitoring service running"));
        }

        return Task.FromResult(HealthCheckResult.Unhealthy("Monitoring service failed"));
    }
}

// Register
builder.Services.AddSingleton<MonitoringService>();
builder.Services.AddHostedService(sp => sp.GetRequiredService<MonitoringService>());
builder.Services.AddHealthChecks()
    .AddCheck<BackgroundServiceHealthCheck>("monitoring-service");
</pre>
</p></div>
<div style="background: linear-gradient(135deg, #d4edda 0%, #c3e6cb 100%); padding: 35px; border-radius: 12px; margin: 40px 0; border-left: 5px solid #28a745;">
<h4 style="color: #155724; margin-top: 0; font-size: 1.7em; font-weight: 700;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Common Use Cases</h4>
<ul style="color: #155724; font-size: 1.15em; line-height: 2.2; margin: 20px 0;">
<li><strong>Email queue processing:</strong> Send emails asynchronously</li>
<li><strong>Data cleanup:</strong> Delete old logs, cache entries</li>
<li><strong>Report generation:</strong> Generate daily/weekly reports</li>
<li><strong>Cache warming:</strong> Preload cache on schedule</li>
<li><strong>Health monitoring:</strong> Check external service health</li>
<li><strong>Batch processing:</strong> Process large datasets in background</li>
</ul></div>
<div style="background: linear-gradient(135deg, #fff3cd 0%, #ffe69c 100%); border-left: 5px solid #ffc107; padding: 35px; margin: 50px 0; border-radius: 12px;">
<h4 style="color: #856404; margin-top: 0; font-size: 1.7em; font-weight: 700;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4a1.png" alt="💡" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Best Practices</h4>
<ul style="color: #856404; font-size: 1.15em; line-height: 2.2; margin: 20px 0;">
<li><strong>Use IServiceProvider:</strong> Create scopes for scoped services</li>
<li><strong>Handle CancellationToken:</strong> Graceful shutdown support</li>
<li><strong>Add error handling:</strong> Don't let exceptions stop service</li>
<li><strong>Log everything:</strong> Track service lifecycle and errors</li>
<li><strong>Use delays, not while(true):</strong> Avoid CPU spinning</li>
<li><strong>Dispose resources:</strong> Override Dispose() when needed</li>
</ul></div>
<blockquote style="background: linear-gradient(to right, #fce4ec, #f8bbd0); border-left: 6px solid #e91e63; padding: 40px; margin: 50px 0; border-radius: 12px;">
<p style="font-size: 1.5em; line-height: 1.9; margin: 0; color: #880e4f; font-style: italic; font-weight: 500;">"Needed to process 100k+ emails daily. Created BackgroundService with queue. Runs 24/7, processes emails in batches. Zero downtime. Easier than setting up separate worker service."</p>
<footer style="margin-top: 20px; color: #ad1457; font-size: 1.15em; font-weight: 600;">— Backend Engineer</footer>
</blockquote>
]]></content:encoded>
					
					<wfw:commentRss>http://blog.ercanopak.com/net-core-use-background-services-for-long-running-tasks/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>.NET Core: Use Minimal APIs for Lightweight HTTP Services</title>
		<link>http://blog.ercanopak.com/net-core-use-minimal-apis-for-lightweight-http-services/</link>
					<comments>http://blog.ercanopak.com/net-core-use-minimal-apis-for-lightweight-http-services/#respond</comments>
		
		<dc:creator><![CDATA[ErcanOPAK]]></dc:creator>
		<pubDate>Mon, 30 Mar 2026 17:51:34 +0000</pubDate>
				<category><![CDATA[Asp.Net Core]]></category>
		<category><![CDATA[.NET 6]]></category>
		<category><![CDATA[.NET 7]]></category>
		<category><![CDATA[.Net Core]]></category>
		<category><![CDATA[ASP.NET Core]]></category>
		<category><![CDATA[C# Tips]]></category>
		<category><![CDATA[microservices]]></category>
		<category><![CDATA[Minimal APIs]]></category>
		<category><![CDATA[Modern .NET]]></category>
		<category><![CDATA[REST API]]></category>
		<category><![CDATA[Web API]]></category>
		<guid isPermaLink="false">http://blog.ercanopak.com/net-core-use-minimal-apis-for-lightweight-http-services/</guid>

					<description><![CDATA[🚀 APIs in 10 Lines of Code MVC Controllers for simple API? Overkill. Minimal APIs (.NET 6+) create HTTP endpoints with minimal ceremony. Perfect for microservices, simple APIs. Traditional Controller vs Minimal API // ❌ Traditional Controller (verbose) [ApiController] [Route("api/[controller]")] public class UsersController : ControllerBase { private readonly IUserService _userService; public UsersController(IUserService userService) { _userService [&#8230;]]]></description>
										<content:encoded><![CDATA[<div style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 50px 40px; border-radius: 16px; margin: 40px 0; box-shadow: 0 20px 60px rgba(0,0,0,0.3);">
<h2 style="margin: 0 0 20px 0; font-size: 2.8em; font-weight: 800; line-height: 1.2;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f680.png" alt="🚀" class="wp-smiley" style="height: 1em; max-height: 1em;" /> APIs in 10 Lines of Code</h2>
<p style="font-size: 1.4em; line-height: 1.8; margin: 0; opacity: 0.95;">MVC Controllers for simple API? Overkill. <strong>Minimal APIs</strong> (.NET 6+) create HTTP endpoints with minimal ceremony. Perfect for microservices, simple APIs.</p>
</p></div>
<h3 style="color: #2c3e50; font-size: 2.2em; margin: 50px 0 30px 0; font-weight: 700; border-left: 5px solid #764ba2; padding-left: 20px;">Traditional Controller vs Minimal API</h3>
<pre class="EnlighterJSRAW" data-enlighter-language="csharp">
// <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/274c.png" alt="❌" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Traditional Controller (verbose)
[ApiController]
[Route("api/[controller]")]
public class UsersController : ControllerBase
{
    private readonly IUserService _userService;
    
    public UsersController(IUserService userService)
    {
        _userService = userService;
    }
    
    [HttpGet]
    public async Task<ActionResult<List<User>>> GetUsers()
    {
        var users = await _userService.GetAllAsync();
        return Ok(users);
    }
    
    [HttpGet("{id}")]
    public async Task<ActionResult<User>> GetUser(int id)
    {
        var user = await _userService.GetByIdAsync(id);
        if (user == null) return NotFound();
        return Ok(user);
    }
    
    [HttpPost]
    public async Task<ActionResult<User>> CreateUser(User user)
    {
        var created = await _userService.CreateAsync(user);
        return CreatedAtAction(nameof(GetUser), new { id = created.Id }, created);
    }
}

// Many files, boilerplate code, ceremony
</pre>
<pre class="EnlighterJSRAW" data-enlighter-language="csharp">
// <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Minimal API (concise!)
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddScoped<IUserService, UserService>();

var app = builder.Build();

app.MapGet("/api/users", async (IUserService service) => 
    await service.GetAllAsync());

app.MapGet("/api/users/{id}", async (int id, IUserService service) =>
{
    var user = await service.GetByIdAsync(id);
    return user is not null ? Results.Ok(user) : Results.NotFound();
});

app.MapPost("/api/users", async (User user, IUserService service) =>
{
    var created = await service.CreateAsync(user);
    return Results.Created($"/api/users/{created.Id}", created);
});

app.Run();

// Everything in Program.cs, minimal code!
</pre>
<div style="background: #f8f9fa; padding: 40px; border-radius: 12px; margin: 40px 0; border: 2px solid #667eea;">
<h4 style="color: #667eea; margin-top: 0; font-size: 1.7em; font-weight: 700;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3af.png" alt="🎯" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Complete CRUD Example</h4>
<pre class="EnlighterJSRAW" data-enlighter-language="csharp">
var builder = WebApplication.CreateBuilder(args);

// Add services
builder.Services.AddDbContext<AppDbContext>();
builder.Services.AddScoped<IUserRepository, UserRepository>();

var app = builder.Build();

// GET all users
app.MapGet("/api/users", async (IUserRepository repo) =>
{
    var users = await repo.GetAllAsync();
    return Results.Ok(users);
})
.WithName("GetUsers")
.Produces<List<User>>(200);

// GET user by ID
app.MapGet("/api/users/{id:int}", async (int id, IUserRepository repo) =>
{
    var user = await repo.GetByIdAsync(id);
    return user is not null 
        ? Results.Ok(user) 
        : Results.NotFound(new { message = "User not found" });
})
.WithName("GetUser")
.Produces<User>(200)
.Produces(404);

// POST create user
app.MapPost("/api/users", async (User user, IUserRepository repo) =>
{
    if (string.IsNullOrWhiteSpace(user.Name))
        return Results.BadRequest(new { message = "Name is required" });
    
    var created = await repo.CreateAsync(user);
    return Results.CreatedAtRoute("GetUser", new { id = created.Id }, created);
})
.Accepts<User>("application/json")
.Produces<User>(201)
.Produces(400);

// PUT update user
app.MapPut("/api/users/{id:int}", async (int id, User user, IUserRepository repo) =>
{
    var existing = await repo.GetByIdAsync(id);
    if (existing is null)
        return Results.NotFound();
    
    user.Id = id;
    await repo.UpdateAsync(user);
    return Results.NoContent();
})
.Produces(204)
.Produces(404);

// DELETE user
app.MapDelete("/api/users/{id:int}", async (int id, IUserRepository repo) =>
{
    var deleted = await repo.DeleteAsync(id);
    return deleted 
        ? Results.NoContent() 
        : Results.NotFound();
})
.Produces(204)
.Produces(404);

app.Run();
</pre>
</p></div>
<h3 style="color: #2c3e50; font-size: 2.2em; margin: 50px 0 30px 0; font-weight: 700; border-left: 5px solid #f39c12; padding-left: 20px;">Dependency Injection</h3>
<pre class="EnlighterJSRAW" data-enlighter-language="csharp">
// Services automatically injected from DI
app.MapGet("/api/products", async (
    IProductService productService,  // Injected
    ILogger<Program> logger,          // Injected
    HttpContext context) =>           // Also available
{
    logger.LogInformation("Getting products for user {User}", context.User.Identity?.Name);
    return await productService.GetAllAsync();
});

// Multiple services
app.MapPost("/api/orders", async (
    Order order,
    IOrderService orderService,
    IInventoryService inventoryService,
    IEmailService emailService) =>
{
    var created = await orderService.CreateAsync(order);
    await inventoryService.UpdateStockAsync(order.Items);
    await emailService.SendOrderConfirmationAsync(created);
    return Results.Created($"/api/orders/{created.Id}", created);
});
</pre>
<div style="background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); color: white; padding: 35px; border-radius: 12px; margin: 40px 0;">
<h4 style="margin-top: 0; font-size: 1.7em; font-weight: 700;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f510.png" alt="🔐" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Authentication &#038; Authorization</h4>
<pre style="background: rgba(0,0,0,0.3); color: #fff; padding: 25px; border-radius: 8px; font-size: 1.05em; line-height: 1.8;">
// Add auth services
builder.Services.AddAuthentication()
    .AddJwtBearer();
builder.Services.AddAuthorization();

var app = builder.Build();

app.UseAuthentication();
app.UseAuthorization();

// Require authentication
app.MapGet("/api/profile", async (HttpContext context) =>
{
    return Results.Ok(new { user = context.User.Identity?.Name });
})
.RequireAuthorization();  // Requires authenticated user

// Require specific role
app.MapDelete("/api/users/{id}", async (int id, IUserRepository repo) =>
{
    await repo.DeleteAsync(id);
    return Results.NoContent();
})
.RequireAuthorization("AdminOnly");

// Require policy
app.MapPost("/api/admin/config", async (Config config) =>
{
    // Admin action
})
.RequireAuthorization(policy => policy.RequireRole("Admin"));
</pre>
</p></div>
<h3 style="color: #2c3e50; font-size: 2.2em; margin: 50px 0 30px 0; font-weight: 700; border-left: 5px solid #27ae60; padding-left: 20px;">Validation &#038; Error Handling</h3>
<pre class="EnlighterJSRAW" data-enlighter-language="csharp">
// Install: FluentValidation.AspNetCore
builder.Services.AddValidatorsFromAssemblyContaining<Program>();

// Validator
public class CreateUserValidator : AbstractValidator<CreateUserDto>
{
    public CreateUserValidator()
    {
        RuleFor(x => x.Email).NotEmpty().EmailAddress();
        RuleFor(x => x.Name).NotEmpty().MaximumLength(100);
        RuleFor(x => x.Age).GreaterThan(0).LessThan(150);
    }
}

// Endpoint with validation
app.MapPost("/api/users", async (
    CreateUserDto dto,
    IValidator<CreateUserDto> validator,
    IUserService service) =>
{
    var validationResult = await validator.ValidateAsync(dto);
    if (!validationResult.IsValid)
    {
        return Results.ValidationProblem(validationResult.ToDictionary());
    }
    
    var user = await service.CreateAsync(dto);
    return Results.Created($"/api/users/{user.Id}", user);
});

// Global exception handler
app.UseExceptionHandler(exceptionHandlerApp =>
{
    exceptionHandlerApp.Run(async context =>
    {
        context.Response.StatusCode = 500;
        context.Response.ContentType = "application/json";
        
        var error = context.Features.Get<IExceptionHandlerFeature>();
        if (error != null)
        {
            await context.Response.WriteAsJsonAsync(new
            {
                error = "An error occurred",
                detail = error.Error.Message
            });
        }
    });
});
</pre>
<div style="background: linear-gradient(135deg, #d4edda 0%, #c3e6cb 100%); padding: 35px; border-radius: 12px; margin: 40px 0; border-left: 5px solid #28a745;">
<h4 style="color: #155724; margin-top: 0; font-size: 1.7em; font-weight: 700;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Benefits of Minimal APIs</h4>
<ul style="color: #155724; font-size: 1.15em; line-height: 2.2; margin: 20px 0;">
<li><strong>Less code:</strong> 50-70% less boilerplate than controllers</li>
<li><strong>Faster startup:</strong> Reduced overhead</li>
<li><strong>Easy to understand:</strong> Everything in one place</li>
<li><strong>Perfect for microservices:</strong> Lightweight, focused</li>
<li><strong>Modern C# features:</strong> Top-level statements, implicit usings</li>
</ul></div>
<div style="background: linear-gradient(135deg, #fff3cd 0%, #ffe69c 100%); border-left: 5px solid #ffc107; padding: 35px; margin: 50px 0; border-radius: 12px;">
<h4 style="color: #856404; margin-top: 0; font-size: 1.7em; font-weight: 700;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4a1.png" alt="💡" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Pro Tips</h4>
<ul style="color: #856404; font-size: 1.15em; line-height: 2.2; margin: 20px 0;">
<li><strong>Use route groups:</strong> Group related endpoints</li>
<li><strong>Add Swagger:</strong> builder.Services.AddEndpointsApiExplorer()</li>
<li><strong>Organize endpoints:</strong> Use extension methods for large apps</li>
<li><strong>Add filters:</strong> .AddEndpointFilter() for cross-cutting concerns</li>
<li><strong>Use Results:</strong> Results.Ok(), Results.NotFound() for typed responses</li>
</ul></div>
<div style="background: #f8f9fa; padding: 40px; border-radius: 12px; margin: 40px 0; border: 2px solid #667eea;">
<h4 style="color: #667eea; margin-top: 0; font-size: 1.7em; font-weight: 700;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3af.png" alt="🎯" class="wp-smiley" style="height: 1em; max-height: 1em;" /> When to Use Minimal APIs</h4>
<table style="width: 100%; border-collapse: collapse; margin: 20px 0;">
<tr style="background: #667eea; color: white;">
<th style="padding: 15px; text-align: left;">Use Minimal APIs</th>
<th style="padding: 15px; text-align: left;">Use Controllers</th>
</tr>
<tr>
<td style="padding: 12px; border-bottom: 1px solid #ddd;">Microservices</td>
<td style="padding: 12px; border-bottom: 1px solid #ddd;">Large monolithic apps</td>
</tr>
<tr style="background: #f8f9fa;">
<td style="padding: 12px; border-bottom: 1px solid #ddd;">Simple CRUD APIs</td>
<td style="padding: 12px; border-bottom: 1px solid #ddd;">Complex business logic</td>
</tr>
<tr>
<td style="padding: 12px; border-bottom: 1px solid #ddd;">Prototypes, POCs</td>
<td style="padding: 12px; border-bottom: 1px solid #ddd;">Team prefers MVC patterns</td>
</tr>
<tr style="background: #f8f9fa;">
<td style="padding: 12px; border-bottom: 1px solid #ddd;">Serverless functions</td>
<td style="padding: 12px; border-bottom: 1px solid #ddd;">Need attribute routing features</td>
</tr>
<tr>
<td style="padding: 12px;">Quick HTTP services</td>
<td style="padding: 12px;">Established codebase with controllers</td>
</tr>
</table></div>
<blockquote style="background: linear-gradient(to right, #e8eaf6, #c5cae9); border-left: 6px solid #5c6bc0; padding: 40px; margin: 50px 0; border-radius: 12px;">
<p style="font-size: 1.5em; line-height: 1.9; margin: 0; color: #1a237e; font-style: italic; font-weight: 500;">&#8220;Rewrote microservice API from MVC to Minimal APIs. Code reduced from 500 lines across 5 files to 150 lines in Program.cs. Startup time halved. Easier for juniors to understand.&#8221;</p>
<footer style="margin-top: 20px; color: #283593; font-size: 1.15em; font-weight: 600;">— .NET Architect</footer>
</blockquote>
]]></content:encoded>
					
					<wfw:commentRss>http://blog.ercanopak.com/net-core-use-minimal-apis-for-lightweight-http-services/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Git: Use Cherry-Pick to Apply Specific Commits Across Branches</title>
		<link>http://blog.ercanopak.com/git-use-cherry-pick-to-apply-specific-commits-across-branches/</link>
					<comments>http://blog.ercanopak.com/git-use-cherry-pick-to-apply-specific-commits-across-branches/#respond</comments>
		
		<dc:creator><![CDATA[ErcanOPAK]]></dc:creator>
		<pubDate>Mon, 30 Mar 2026 17:51:27 +0000</pubDate>
				<category><![CDATA[Git]]></category>
		<category><![CDATA[Best Practices]]></category>
		<category><![CDATA[branching]]></category>
		<category><![CDATA[Cherry Pick]]></category>
		<category><![CDATA[Code Management]]></category>
		<category><![CDATA[Git Commands]]></category>
		<category><![CDATA[Git Tips]]></category>
		<category><![CDATA[Git Workflow]]></category>
		<category><![CDATA[Hotfix]]></category>
		<category><![CDATA[Version Control]]></category>
		<guid isPermaLink="false">http://blog.ercanopak.com/git-use-cherry-pick-to-apply-specific-commits-across-branches/</guid>

					<description><![CDATA[🍒 Pick Commits Like Cherries Need one commit from another branch? Don&#8217;t merge everything. Cherry-pick copies specific commits to your current branch. Surgical precision. The Problem # Scenario: Bug fix on wrong branch git branch * feature-login main hotfix # You committed bug fix to feature-login # But it needs to be on hotfix branch [&#8230;]]]></description>
										<content:encoded><![CDATA[<div style="background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); color: white; padding: 50px 40px; border-radius: 16px; margin: 40px 0; box-shadow: 0 20px 60px rgba(0,0,0,0.3);">
<h2 style="margin: 0 0 20px 0; font-size: 2.8em; font-weight: 800; line-height: 1.2;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f352.png" alt="🍒" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Pick Commits Like Cherries</h2>
<p style="font-size: 1.4em; line-height: 1.8; margin: 0; opacity: 0.95;">Need one commit from another branch? Don&#8217;t merge everything. <strong>Cherry-pick</strong> copies specific commits to your current branch. Surgical precision.</p>
</p></div>
<h3 style="color: #2c3e50; font-size: 2.2em; margin: 50px 0 30px 0; font-weight: 700; border-left: 5px solid #00f2fe; padding-left: 20px;">The Problem</h3>
<pre class="EnlighterJSRAW" data-enlighter-language="bash">
# Scenario: Bug fix on wrong branch
git branch
* feature-login
  main
  hotfix

# You committed bug fix to feature-login
# But it needs to be on hotfix branch too!

git log --oneline
a1b2c3d Fix critical security bug  ← Need this on hotfix!
d4e5f6g Add login form
g7h8i9j Update styles

# Don't want to merge entire feature branch
# Just need the security fix
</pre>
<h3 style="color: #2c3e50; font-size: 2.2em; margin: 50px 0 30px 0; font-weight: 700; border-left: 5px solid #27ae60; padding-left: 20px;">Cherry-Pick Solution</h3>
<pre class="EnlighterJSRAW" data-enlighter-language="bash">
# Switch to target branch
git checkout hotfix

# Cherry-pick the commit
git cherry-pick a1b2c3d

# Done! Commit copied to hotfix branch
git log --oneline
a1b2c3d Fix critical security bug  ← Same commit, now on hotfix!
x7y8z9a Previous hotfix commit
</pre>
<div style="background: #f8f9fa; padding: 40px; border-radius: 12px; margin: 40px 0; border: 2px solid #4facfe;">
<h4 style="color: #00f2fe; margin-top: 0; font-size: 1.7em; font-weight: 700;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3af.png" alt="🎯" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Common Use Cases</h4>
<h5 style="color: #667eea; font-size: 1.4em; margin: 25px 0 15px 0;">1. Bug Fix on Wrong Branch</h5>
<pre class="EnlighterJSRAW" data-enlighter-language="bash">
# Fixed bug on feature branch, need on main
git checkout main
git cherry-pick abc123

# Or cherry-pick from another person's branch
git cherry-pick origin/their-branch-name~2  # 2 commits ago
</pre>
<h5 style="color: #667eea; font-size: 1.4em; margin: 25px 0 15px 0;">2. Apply Multiple Commits</h5>
<pre class="EnlighterJSRAW" data-enlighter-language="bash">
# Cherry-pick range of commits
git cherry-pick abc123..def456

# Cherry-pick multiple specific commits
git cherry-pick abc123 def456 ghi789

# Cherry-pick all commits from another branch
git cherry-pick feature-branch
</pre>
<h5 style="color: #667eea; font-size: 1.4em; margin: 25px 0 15px 0;">3. Hotfix to Multiple Versions</h5>
<pre class="EnlighterJSRAW" data-enlighter-language="bash">
# Apply same fix to v1.0, v2.0, v3.0 branches
git checkout v1.0-stable
git cherry-pick abc123

git checkout v2.0-stable
git cherry-pick abc123

git checkout v3.0-stable
git cherry-pick abc123

# Same fix on all versions!
</pre>
</p></div>
<h3 style="color: #2c3e50; font-size: 2.2em; margin: 50px 0 30px 0; font-weight: 700; border-left: 5px solid #f39c12; padding-left: 20px;">Handle Conflicts</h3>
<pre class="EnlighterJSRAW" data-enlighter-language="bash">
git cherry-pick abc123

# If conflicts:
# CONFLICT (content): Merge conflict in file.js

# Fix conflicts
vim file.js  # Resolve conflicts

# Mark as resolved
git add file.js

# Continue cherry-pick
git cherry-pick --continue

# Or abort
git cherry-pick --abort
</pre>
<div style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 35px; border-radius: 12px; margin: 40px 0;">
<h4 style="margin-top: 0; font-size: 1.7em; font-weight: 700;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f527.png" alt="🔧" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Advanced Options</h4>
<pre style="background: rgba(0,0,0,0.3); color: #fff; padding: 25px; border-radius: 8px; font-size: 1.05em; line-height: 1.8;">
# Cherry-pick without committing (stage changes only)
git cherry-pick -n abc123
# Make modifications, then commit manually

# Cherry-pick and edit commit message
git cherry-pick -e abc123

# Add 'cherry picked from' note to commit message
git cherry-pick -x abc123
# Adds: (cherry picked from commit abc123)

# Cherry-pick but with different author
git cherry-pick abc123
git commit --amend --author="John Doe <john@example.com>"

# Cherry-pick only the changes, not the commit
git cherry-pick -n abc123
git reset  # Unstage
# Now you have changes in working directory
</pre>
</p></div>
<h3 style="color: #2c3e50; font-size: 2.2em; margin: 50px 0 30px 0; font-weight: 700; border-left: 5px solid #667eea; padding-left: 20px;">Real-World Workflow</h3>
<div style="background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); color: white; padding: 35px; border-radius: 12px; margin: 40px 0;">
<h4 style="margin-top: 0; font-size: 1.7em; font-weight: 700;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4cb.png" alt="📋" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Production Hotfix Workflow</h4>
<pre style="background: rgba(0,0,0,0.3); color: #fff; padding: 25px; border-radius: 8px; font-size: 1.05em; line-height: 1.8;">
# Bug found in production!
# Create hotfix branch from main
git checkout main
git checkout -b hotfix-critical-bug

# Fix bug, commit
git commit -m "Fix critical login bug"
# Commit hash: xyz789

# Deploy hotfix to production
git checkout main
git merge hotfix-critical-bug
git push

# Now cherry-pick to development branch
git checkout develop
git cherry-pick xyz789

# Now cherry-pick to all active feature branches
git checkout feature-new-ui
git cherry-pick xyz789

git checkout feature-api-v2
git cherry-pick xyz789

# Same fix everywhere!
</pre>
</p></div>
<div style="background: linear-gradient(135deg, #d4edda 0%, #c3e6cb 100%); padding: 35px; border-radius: 12px; margin: 40px 0; border-left: 5px solid #28a745;">
<h4 style="color: #155724; margin-top: 0; font-size: 1.7em; font-weight: 700;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> When to Use Cherry-Pick</h4>
<ul style="color: #155724; font-size: 1.15em; line-height: 2.2; margin: 20px 0;">
<li><strong>Bug fixes:</strong> Apply to multiple branches/versions</li>
<li><strong>Backporting:</strong> Bring new features to old versions</li>
<li><strong>Mistakes:</strong> Commit on wrong branch, move it</li>
<li><strong>Selective merging:</strong> Want some commits, not all</li>
<li><strong>Team collaboration:</strong> Grab colleague&#8217;s commit</li>
</ul></div>
<div style="background: linear-gradient(135deg, #fff3cd 0%, #ffe69c 100%); border-left: 5px solid #ffc107; padding: 35px; margin: 50px 0; border-radius: 12px;">
<h4 style="color: #856404; margin-top: 0; font-size: 1.7em; font-weight: 700;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/26a0.png" alt="⚠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Caveats</h4>
<ul style="color: #856404; font-size: 1.15em; line-height: 2.2; margin: 20px 0;">
<li><strong>Creates duplicate commits:</strong> Same change, different hash</li>
<li><strong>Can cause conflicts:</strong> If code has diverged</li>
<li><strong>Loses context:</strong> Commit might not make sense alone</li>
<li><strong>Tracking is harder:</strong> Git doesn&#8217;t track cherry-picks automatically</li>
<li><strong>Prefer merge when possible:</strong> Cherry-pick is for exceptions</li>
</ul></div>
<div style="background: #f8f9fa; padding: 40px; border-radius: 12px; margin: 40px 0; border: 2px solid #4facfe;">
<h4 style="color: #00f2fe; margin-top: 0; font-size: 1.7em; font-weight: 700;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4a1.png" alt="💡" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Pro Tips</h4>
<pre class="EnlighterJSRAW" data-enlighter-language="bash">
# Find commits to cherry-pick
git log --oneline --graph branch-name

# Cherry-pick from reflog (even deleted commits!)
git reflog
git cherry-pick abc123

# Test before cherry-picking
git show abc123  # View commit changes

# Cherry-pick merge commit (requires -m)
git cherry-pick -m 1 merge-commit-hash
# -m 1 means use first parent

# Undo cherry-pick
git reset --hard HEAD~1  # If not pushed
git revert commit-hash   # If already pushed
</pre>
</p></div>
<div style="background: #f8f9fa; padding: 40px; border-radius: 12px; margin: 40px 0; border: 2px solid #4facfe;">
<h4 style="color: #00f2fe; margin-top: 0; font-size: 1.7em; font-weight: 700;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3af.png" alt="🎯" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Cheat Sheet</h4>
<table style="width: 100%; border-collapse: collapse; margin: 20px 0;">
<tr style="background: #4facfe; color: white;">
<th style="padding: 15px; text-align: left;">Command</th>
<th style="padding: 15px; text-align: left;">Action</th>
</tr>
<tr>
<td style="padding: 12px; border-bottom: 1px solid #ddd;"><code>git cherry-pick abc123</code></td>
<td style="padding: 12px; border-bottom: 1px solid #ddd;">Apply single commit</td>
</tr>
<tr style="background: #f8f9fa;">
<td style="padding: 12px; border-bottom: 1px solid #ddd;"><code>git cherry-pick abc..def</code></td>
<td style="padding: 12px; border-bottom: 1px solid #ddd;">Apply range of commits</td>
</tr>
<tr>
<td style="padding: 12px; border-bottom: 1px solid #ddd;"><code>git cherry-pick -n abc123</code></td>
<td style="padding: 12px; border-bottom: 1px solid #ddd;">Don&#8217;t commit (stage only)</td>
</tr>
<tr style="background: #f8f9fa;">
<td style="padding: 12px; border-bottom: 1px solid #ddd;"><code>git cherry-pick -x abc123</code></td>
<td style="padding: 12px; border-bottom: 1px solid #ddd;">Add source note to message</td>
</tr>
<tr>
<td style="padding: 12px; border-bottom: 1px solid #ddd;"><code>git cherry-pick --continue</code></td>
<td style="padding: 12px; border-bottom: 1px solid #ddd;">Continue after conflict</td>
</tr>
<tr style="background: #f8f9fa;">
<td style="padding: 12px;"><code>git cherry-pick --abort</code></td>
<td style="padding: 12px;">Cancel cherry-pick</td>
</tr>
</table></div>
<blockquote style="background: linear-gradient(to right, #e0f7fa, #b2ebf2); border-left: 6px solid #00bcd4; padding: 40px; margin: 50px 0; border-radius: 12px;">
<p style="font-size: 1.5em; line-height: 1.9; margin: 0; color: #006064; font-style: italic; font-weight: 500;">&#8220;Critical security fix needed in 3 production versions simultaneously. Cherry-picked same commit to v1, v2, v3 branches. All versions patched in 10 minutes. Cherry-pick saved the day.&#8221;</p>
<footer style="margin-top: 20px; color: #00838f; font-size: 1.15em; font-weight: 600;">— DevOps Engineer</footer>
</blockquote>
]]></content:encoded>
					
					<wfw:commentRss>http://blog.ercanopak.com/git-use-cherry-pick-to-apply-specific-commits-across-branches/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Git: Use Interactive Rebase to Clean Up Commit History Before Merge</title>
		<link>http://blog.ercanopak.com/git-use-interactive-rebase-to-clean-up-commit-history-before-merge/</link>
					<comments>http://blog.ercanopak.com/git-use-interactive-rebase-to-clean-up-commit-history-before-merge/#respond</comments>
		
		<dc:creator><![CDATA[ErcanOPAK]]></dc:creator>
		<pubDate>Mon, 30 Mar 2026 17:51:20 +0000</pubDate>
				<category><![CDATA[Git]]></category>
		<category><![CDATA[Best Practices]]></category>
		<category><![CDATA[Code Review]]></category>
		<category><![CDATA[Git History]]></category>
		<category><![CDATA[Git Rebase]]></category>
		<category><![CDATA[Git Tips]]></category>
		<category><![CDATA[Git Workflow]]></category>
		<category><![CDATA[Interactive Rebase]]></category>
		<category><![CDATA[Squash Commits]]></category>
		<category><![CDATA[Version Control]]></category>
		<guid isPermaLink="false">http://blog.ercanopak.com/git-use-interactive-rebase-to-clean-up-commit-history-before-merge/</guid>

					<description><![CDATA[🔧 Rewrite Git History 50 commits saying &#8216;fix typo&#8217;, &#8216;WIP&#8217;, &#8216;oops&#8217;? Messy history before PR? Interactive rebase lets you squash, reword, reorder commits. Clean history like a pro. The Messy History Problem git log --oneline a1b2c3d fix typo d4e5f6g WIP g7h8i9j oops forgot file j1k2l3m fix typo again m4n5o6p actually fix the bug p7q8r9s Add [&#8230;]]]></description>
										<content:encoded><![CDATA[<div style="background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%); color: white; padding: 50px 40px; border-radius: 16px; margin: 40px 0; box-shadow: 0 20px 60px rgba(0,0,0,0.3);">
<h2 style="margin: 0 0 20px 0; font-size: 2.8em; font-weight: 800; line-height: 1.2;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f527.png" alt="🔧" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Rewrite Git History</h2>
<p style="font-size: 1.4em; line-height: 1.8; margin: 0; opacity: 0.95;">50 commits saying &#8216;fix typo&#8217;, &#8216;WIP&#8217;, &#8216;oops&#8217;? Messy history before PR? <strong>Interactive rebase</strong> lets you squash, reword, reorder commits. Clean history like a pro.</p>
</p></div>
<h3 style="color: #2c3e50; font-size: 2.2em; margin: 50px 0 30px 0; font-weight: 700; border-left: 5px solid #f5576c; padding-left: 20px;">The Messy History Problem</h3>
<pre class="EnlighterJSRAW" data-enlighter-language="bash">
git log --oneline

a1b2c3d fix typo
d4e5f6g WIP
g7h8i9j oops forgot file
j1k2l3m fix typo again
m4n5o6p actually fix the bug
p7q8r9s Add feature X

# 6 commits for 1 feature!
# Confusing for code review
# Clutters git history
</pre>
<h3 style="color: #2c3e50; font-size: 2.2em; margin: 50px 0 30px 0; font-weight: 700; border-left: 5px solid #27ae60; padding-left: 20px;">Interactive Rebase to Rescue</h3>
<pre class="EnlighterJSRAW" data-enlighter-language="bash">
# Rebase last 6 commits
git rebase -i HEAD~6

# Or rebase from specific commit
git rebase -i a1b2c3d

# Editor opens with commit list:
pick a1b2c3d fix typo
pick d4e5f6g WIP
pick g7h8i9j oops forgot file
pick j1k2l3m fix typo again
pick m4n5o6p actually fix the bug
pick p7q8r9s Add feature X

# Commands available:
# pick   = use commit
# reword = use commit, but edit message
# edit   = use commit, but stop for amending
# squash = use commit, combine with previous
# fixup  = like squash, discard commit message
# drop   = remove commit
</pre>
<div style="background: #f8f9fa; padding: 40px; border-radius: 12px; margin: 40px 0; border: 2px solid #f093fb;">
<h4 style="color: #f5576c; margin-top: 0; font-size: 1.7em; font-weight: 700;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3af.png" alt="🎯" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Common Rebase Actions</h4>
<h5 style="color: #667eea; font-size: 1.4em; margin: 25px 0 15px 0;">1. Squash Commits</h5>
<pre class="EnlighterJSRAW" data-enlighter-language="bash">
# Combine multiple commits into one
pick p7q8r9s Add feature X
squash m4n5o6p actually fix the bug
squash j1k2l3m fix typo again
squash g7h8i9j oops forgot file
squash d4e5f6g WIP
squash a1b2c3d fix typo

# Save and close
# New editor opens for combined commit message
# Result: 6 commits → 1 clean commit
</pre>
<h5 style="color: #667eea; font-size: 1.4em; margin: 25px 0 15px 0;">2. Fixup (Squash Without Message)</h5>
<pre class="EnlighterJSRAW" data-enlighter-language="bash">
pick p7q8r9s Add feature X
fixup m4n5o6p actually fix the bug
fixup j1k2l3m fix typo again
fixup g7h8i9j oops forgot file
fixup d4e5f6g WIP
fixup a1b2c3d fix typo

# Like squash, but automatically uses first commit's message
# No need to edit combined message
</pre>
<h5 style="color: #667eea; font-size: 1.4em; margin: 25px 0 15px 0;">3. Reword Commit Messages</h5>
<pre class="EnlighterJSRAW" data-enlighter-language="bash">
reword a1b2c3d fix typo
pick d4e5f6g Add authentication

# Editor opens for each 'reword'
# Change message, save, continue
</pre>
<h5 style="color: #667eea; font-size: 1.4em; margin: 25px 0 15px 0;">4. Reorder Commits</h5>
<pre class="EnlighterJSRAW" data-enlighter-language="bash">
# Just reorder lines
pick d4e5f6g Add tests
pick a1b2c3d Add feature
pick g7h8i9j Update docs

# Changes order in history
</pre>
<h5 style="color: #667eea; font-size: 1.4em; margin: 25px 0 15px 0;">5. Drop Commits</h5>
<pre class="EnlighterJSRAW" data-enlighter-language="bash">
pick a1b2c3d Add feature
drop d4e5f6g debug logging
pick g7h8i9j Update docs

# Or just delete the line (same effect)
pick a1b2c3d Add feature
pick g7h8i9j Update docs
</pre>
</p></div>
<h3 style="color: #2c3e50; font-size: 2.2em; margin: 50px 0 30px 0; font-weight: 700; border-left: 5px solid #667eea; padding-left: 20px;">Real-World Workflow</h3>
<div style="background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%); color: white; padding: 35px; border-radius: 12px; margin: 40px 0;">
<h4 style="margin-top: 0; font-size: 1.7em; font-weight: 700;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4cb.png" alt="📋" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Before PR Cleanup</h4>
<pre style="background: rgba(0,0,0,0.3); color: #fff; padding: 25px; border-radius: 8px; font-size: 1.05em; line-height: 1.8;">
# You've been working on feature branch
git log --oneline
a1b2c3d fix lint error
d4e5f6g remove console.log
g7h8i9j WIP save work
j1k2l3m add login component
m4n5o6p fix button style
p7q8r9s add logout
q1r2s3t initial auth setup

# Clean up before PR
git rebase -i HEAD~7

# In editor:
pick q1r2s3t initial auth setup
fixup j1k2l3m add login component
fixup p7q8r9s add logout
fixup m4n5o6p fix button style
fixup g7h8i9j WIP save work
fixup d4e5f6g remove console.log
fixup a1b2c3d fix lint error

# Save, close
# Result: 1 clean commit "Add authentication system"

git log --oneline
t4u5v6w Add authentication system

# Beautiful history for PR!
</pre>
</p></div>
<h3 style="color: #2c3e50; font-size: 2.2em; margin: 50px 0 30px 0; font-weight: 700; border-left: 5px solid #f39c12; padding-left: 20px;">Handle Conflicts</h3>
<pre class="EnlighterJSRAW" data-enlighter-language="bash">
# If conflicts during rebase
git rebase -i HEAD~5

# Git stops:
# CONFLICT (content): Merge conflict in file.js

# Fix conflicts in file
vim file.js  # Resolve conflicts

# Mark as resolved
git add file.js

# Continue rebase
git rebase --continue

# Or abort if things go wrong
git rebase --abort
</pre>
<div style="background: linear-gradient(135deg, #d4edda 0%, #c3e6cb 100%); padding: 35px; border-radius: 12px; margin: 40px 0; border-left: 5px solid #28a745;">
<h4 style="color: #155724; margin-top: 0; font-size: 1.7em; font-weight: 700;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/2705.png" alt="✅" class="wp-smiley" style="height: 1em; max-height: 1em;" /> When to Use Interactive Rebase</h4>
<ul style="color: #155724; font-size: 1.15em; line-height: 2.2; margin: 20px 0;">
<li><strong>Before PR/MR:</strong> Clean up feature branch history</li>
<li><strong>WIP commits:</strong> Squash &#8216;work in progress&#8217; commits</li>
<li><strong>Fix commit messages:</strong> Typos, unclear messages</li>
<li><strong>Reorder logical flow:</strong> Tests before implementation</li>
<li><strong>Remove sensitive data:</strong> Accidentally committed secrets</li>
</ul></div>
<div style="background: linear-gradient(135deg, #fff3cd 0%, #ffe69c 100%); border-left: 5px solid #ffc107; padding: 35px; margin: 50px 0; border-radius: 12px;">
<h4 style="color: #856404; margin-top: 0; font-size: 1.7em; font-weight: 700;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/26a0.png" alt="⚠" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Important Rules</h4>
<ul style="color: #856404; font-size: 1.15em; line-height: 2.2; margin: 20px 0;">
<li><strong>Never rebase public branches:</strong> Only rebase local/feature branches</li>
<li><strong>Don&#8217;t rebase after push:</strong> Rewrites history, breaks others&#8217; work</li>
<li><strong>Force push required:</strong> git push &#8211;force-with-lease after rebase</li>
<li><strong>Communicate with team:</strong> If others are working on same branch</li>
<li><strong>Keep backups:</strong> git branch backup-branch before rebase</li>
</ul></div>
<div style="background: #f8f9fa; padding: 40px; border-radius: 12px; margin: 40px 0; border: 2px solid #f093fb;">
<h4 style="color: #f5576c; margin-top: 0; font-size: 1.7em; font-weight: 700;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f4a1.png" alt="💡" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Pro Tips</h4>
<pre class="EnlighterJSRAW" data-enlighter-language="bash">
# Auto-squash: Prepare commits for easy squashing
git commit --fixup a1b2c3d  # Creates fixup! commit
git rebase -i --autosquash HEAD~10  # Auto-arranges fixups

# Set autosquash as default
git config --global rebase.autosquash true

# Use different editor
git config --global core.editor "code --wait"

# Rebase onto different branch
git rebase -i main  # Rebase current branch onto main

# Split a commit
# 1. Mark commit as 'edit'
# 2. Git stops at that commit
# 3. git reset HEAD^
# 4. git add -p (stage hunks separately)
# 5. git commit (multiple times)
# 6. git rebase --continue
</pre>
</p></div>
<div style="background: #f8f9fa; padding: 40px; border-radius: 12px; margin: 40px 0; border: 2px solid #f093fb;">
<h4 style="color: #f5576c; margin-top: 0; font-size: 1.7em; font-weight: 700;"><img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f3af.png" alt="🎯" class="wp-smiley" style="height: 1em; max-height: 1em;" /> Cheat Sheet</h4>
<table style="width: 100%; border-collapse: collapse; margin: 20px 0;">
<tr style="background: #f093fb; color: white;">
<th style="padding: 15px; text-align: left;">Command</th>
<th style="padding: 15px; text-align: left;">Action</th>
</tr>
<tr>
<td style="padding: 12px; border-bottom: 1px solid #ddd;"><code>git rebase -i HEAD~N</code></td>
<td style="padding: 12px; border-bottom: 1px solid #ddd;">Rebase last N commits</td>
</tr>
<tr style="background: #f8f9fa;">
<td style="padding: 12px; border-bottom: 1px solid #ddd;"><code>pick</code></td>
<td style="padding: 12px; border-bottom: 1px solid #ddd;">Keep commit as-is</td>
</tr>
<tr>
<td style="padding: 12px; border-bottom: 1px solid #ddd;"><code>squash</code></td>
<td style="padding: 12px; border-bottom: 1px solid #ddd;">Combine with previous</td>
</tr>
<tr style="background: #f8f9fa;">
<td style="padding: 12px; border-bottom: 1px solid #ddd;"><code>fixup</code></td>
<td style="padding: 12px; border-bottom: 1px solid #ddd;">Squash, discard message</td>
</tr>
<tr>
<td style="padding: 12px; border-bottom: 1px solid #ddd;"><code>reword</code></td>
<td style="padding: 12px; border-bottom: 1px solid #ddd;">Edit commit message</td>
</tr>
<tr style="background: #f8f9fa;">
<td style="padding: 12px; border-bottom: 1px solid #ddd;"><code>drop</code></td>
<td style="padding: 12px; border-bottom: 1px solid #ddd;">Remove commit</td>
</tr>
<tr>
<td style="padding: 12px;"><code>git rebase --abort</code></td>
<td style="padding: 12px;">Cancel rebase</td>
</tr>
</table></div>
<blockquote style="background: linear-gradient(to right, #fce4ec, #f8bbd0); border-left: 6px solid #e91e63; padding: 40px; margin: 50px 0; border-radius: 12px;">
<p style="font-size: 1.5em; line-height: 1.9; margin: 0; color: #880e4f; font-style: italic; font-weight: 500;">&#8220;Used to submit PRs with 30+ WIP commits. Reviewers complained. Learned interactive rebase. Now: 3-5 clean, logical commits per PR. Reviews take half the time. Team loves me.&#8221;</p>
<footer style="margin-top: 20px; color: #ad1457; font-size: 1.15em; font-weight: 600;">— Senior Developer</footer>
</blockquote>
]]></content:encoded>
					
					<wfw:commentRss>http://blog.ercanopak.com/git-use-interactive-rebase-to-clean-up-commit-history-before-merge/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
