在 C# 開發中,將對象序列化後存入數據庫是常見需求。無論是緩存複雜對象、保存用戶會話,還是實現異構系統數據交換,掌握序列化存儲技術都至關重要。本文將詳細介紹如何將可序列化對象存入數據庫字段,以及如何正確讀取還原。
首先,目標類必須標記 [Serializable] 屬性,或實現 ISerializable 接口:
[Serializable]
public class UserProfile
{
public int UserId { get; set; }
public string UserName { get; set; }
public Dictionary<string, object> Preferences { get; set; }
public DateTime LastLogin { get; set; }
}
常用兩種方式:
BinaryFormatter,體積小、速度快,但不可跨平台。Newtonsoft.Json 或 System.Text.Json,可讀性強、跨語言兼容,推薦用於現代應用。數據庫表設計建議使用 VARBINARY(MAX) (SQL Server) 或 BLOB (MySQL) 類型存儲二進制數據,或 NVARCHAR(MAX)/TEXT 存儲 JSON 字符串。
public void SaveBinary(UserProfile profile, string connStr)
{
using (var conn = new SqlConnection(connStr))
using (var cmd = new SqlCommand("UPDATE Users SET ProfileData = @data WHERE UserId = @id", conn))
{
cmd.Parameters.Add("@id", SqlDbType.Int).Value = profile.UserId;
using (var ms = new MemoryStream())
{
new BinaryFormatter().Serialize(ms, profile);
cmd.Parameters.Add("@data", SqlDbType.VarBinary).Value = ms.ToArray();
}
conn.Open();
cmd.ExecuteNonQuery();
}
}
public void SaveJson(UserProfile profile, string connStr)
{
string json = JsonConvert.SerializeObject(profile);
using (var conn = new SqlConnection(connStr))
using (var cmd = new SqlCommand("UPDATE Users SET ProfileJson = @json WHERE UserId = @id", conn))
{
cmd.Parameters.Add("@id", SqlDbType.Int).Value = profile.UserId;
cmd.Parameters.Add("@json", SqlDbType.NVarChar).Value = json;
conn.Open();
cmd.ExecuteNonQuery();
}
}
public UserProfile LoadBinary(int userId, string connStr)
{
using (var conn = new SqlConnection(connStr))
using (var cmd = new SqlCommand("SELECT ProfileData FROM Users WHERE UserId = @id", conn))
{
cmd.Parameters.Add("@id", SqlDbType.Int).Value = userId;
conn.Open();
var data = cmd.ExecuteScalar() as byte[];
if (data == null) return null;
using (var ms = new MemoryStream(data))
{
return (UserProfile)new BinaryFormatter().Deserialize(ms);
}
}
}
public UserProfile LoadJson(int userId, string connStr)
{
using (var conn = new SqlConnection(connStr))
using (var cmd = new SqlCommand("SELECT ProfileJson FROM Users WHERE UserId = @id", conn))
{
cmd.Parameters.Add("@id", SqlDbType.Int).Value = userId;
conn.Open();
string json = cmd.ExecuteScalar() as string;
return string.IsNullOrEmpty(json) ? null : JsonConvert.DeserializeObject<UserProfile>(json);
}
}
BinaryFormatter 存在安全風險,微軟已標記為過時,新項目建議使用 JSON 或 System.Text.Json。C# 對象序列化存入數據庫的核心流程是:標記可序列化 → 選擇序列化格式 → 寫入二進制/文本字段 → 讀取後反序列化。現代開發強烈推薦使用 JSON 格式,配合參數化查詢確保安全,並根據業務場景權衡存儲效率與查詢靈活性。