6.7 KiB
Choosing the right datatype for integer values, specially IDs (Chat GPT):
1 Integer Data Types (int, short, long) in C# and SQL Server
| C# Type | SQL Server Type | Size | Range |
|---|---|---|---|
byte |
TINYINT |
1 byte | 0 to 255 |
short |
SMALLINT |
2 bytes | -32,768 to 32,767 |
int |
INT |
4 bytes | -2,147,483,648 to 2,147,483,647 |
long |
BIGINT |
8 bytes | -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 |
❗ Important Notes:
- The ranges are the same in C# and SQL Server because both use the same underlying storage.
SMALLINTandTINYINTsave space, but be careful about hitting the limit.BIGINTis needed only if you expect billions of records.
2 What to Use for User ID, Ticket ID, Gender ID? (Some examples)
| Field | Recommended C# Type | SQL Server Type | Why? |
|---|---|---|---|
UserId |
int or long |
INT or BIGINT |
INT is usually enough unless expecting billions of users. |
TicketId |
int or long |
INT or BIGINT |
Use BIGINT if expecting massive ticket volumes. |
GenderId |
byte or short |
TINYINT or SMALLINT |
Gender options are limited, so TINYINT is sufficient. |
CompanyId |
int |
INT |
Companies are limited, INT is fine. |
VehicleId |
int |
INT |
Use INT, as vehicle count is manageable. |
Price |
decimal(18,2) |
DECIMAL(18,2) |
Avoid float/double due to rounding issues. |
3 Should I Use GUIDs for User IDs or Ticket IDs?
- Use
GUID(UNIQUEIDENTIFIER) for IDs only if:- Data is distributed across multiple databases.
- Security is critical (e.g., preventing sequential guessing of IDs).
- Otherwise, stick with
intorlongfor performance.
📌 Example in C# (EF Core Model):
public class Ticket
{
public int TicketId { get; set; } // Primary key
public int UserId { get; set; } // Foreign key
public decimal Price { get; set; } // Use decimal for money
public DateTime PurchaseDate { get; set; }
}
📌 Fluent API (SQL Mapping)
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Ticket>()
.Property(t => t.Price)
.HasColumnType("DECIMAL(18,2)");
}
**required keyword (Chat GPT) :
C# IntelliSense suggests adding required to string properties because of nullable reference types (NRT) introduced in C# 8.0+.
2 What Does required Do?
requiredforces initialization of the property when creating an object.- It is not a data annotation (like
[Required]in EF Core), but a C# keyword that affects compile-time checks.
📌 Example Without required
public class User
{
public string Name { get; set; } // Warning: "Non-nullable property 'Name' is uninitialized"
}
🔴 Problem: The compiler warns that Name is not initialized.
✅ Fix: Add required or initialize the property.
📌 Example With required
public class User
{
public required string Name { get; set; } // No warning
}
✅ Effect: You must provide Name when creating a User object.
var user = new User { Name = "Mehrdad" }; // ✅ Works
var invalidUser = new User(); // ❌ Compilation Error: Name is required
A note about strings in C# (Chat GPT) :
string is nullable in C#, but in nullable reference types (C# 8+), string is treated as non-nullable unless explicitly marked string?.
string→ Default behavior (non-nullable by default in nullable context).string?→ Explicitly nullable.
Why virtual navigation properties? (Chat GPT):
- If you mark a navigation property as
virtual, EF Core creates a proxy class at runtime that overrides the property and loads related data only when accessed. - This is called Lazy Loading, meaning data is not fetched until needed.
- If you don’t mark it as
virtual, you must load relationships using.Include()(Eager Loading).
What Type Should Navigation Properties Be?
| Scenario | Recommended Type | Why? |
|---|---|---|
Single reference (e.g., Ticket → Transportation) |
virtual Transportation |
Represents a one-to-one or many-to-one relationship. |
Collection of related entities (e.g., Transportation → Tickets) |
virtual ICollection<Ticket> |
Best for one-to-many relationships, supports lazy loading. |
| Alternative for collections | virtual List<Ticket> |
Works the same, but EF prefers ICollection<T>. |
Using IEnumerable<T> |
❌ Avoid | EF does not recognize IEnumerable<T> for navigation properties. |
One Scenario to look after if using lazy loading:
What is the N+1 Query Problem?
The N+1 query problem happens when EF Core makes too many separate database queries instead of loading data efficiently.
Example Scenario
Let’s say you have 100 tickets, and each ticket has a related Transportation entity.
You run this code:
var tickets = context.Tickets.ToList(); // Loads all tickets foreach (var ticket in tickets)
{
Console.WriteLine(ticket.Transportation.Name); // Lazy loads Transportation for each ticket
}
What Happens?
- 1 Query: EF Core first loads all
Tickets. - N Queries: Then, for each Ticket, EF Core makes a separate query to fetch
Transportation(so 100 additional queries). - Total Queries: 1 + 100 = 101 queries! 🚨 Bad performance!