這個(gè)方法有些地方用著還是挺省事,優(yōu)點(diǎn),缺點(diǎn)明顯。在現(xiàn)代企業(yè)應(yīng)用程序開(kāi)發(fā)中,處理復(fù)雜的主從數(shù)據(jù)結(jié)構(gòu)是常見(jiàn)的需求。例如,在訂單管理系統(tǒng)中,一個(gè)訂單(主數(shù)據(jù))會(huì)有多個(gè)訂單項(xiàng)(子數(shù)據(jù))。傳統(tǒng)的關(guān)系型數(shù)據(jù)庫(kù)可能需要多表關(guān)聯(lián)和復(fù)雜的事務(wù)處理,而通過(guò)將子數(shù)據(jù)保存為JSON字符串,可以簡(jiǎn)化這些繁瑣的操作。本文將詳細(xì)介紹如何在C#中實(shí)現(xiàn)這個(gè)過(guò)程。
1. 背景介紹
主數(shù)據(jù)與子數(shù)據(jù)
主數(shù)據(jù)與子數(shù)據(jù)的關(guān)系可以通過(guò)一個(gè)簡(jiǎn)單的實(shí)例來(lái)描述。假設(shè)我們有一個(gè)訂單表(Order)和訂單項(xiàng)表(OrderItem)。
優(yōu)化思路
通過(guò)將 OrderItem
轉(zhuǎn)換為 JSON 字符串,并將其存儲(chǔ)到 Order
表中的一個(gè)字段中,可以簡(jiǎn)化數(shù)據(jù)結(jié)構(gòu)和操作復(fù)雜性。雖然這種方法降低了數(shù)據(jù)的規(guī)范化程度,但在很多場(chǎng)景下,可以提高開(kāi)發(fā)和維護(hù)效率。
2. 示例實(shí)現(xiàn)
2.1 創(chuàng)建實(shí)體類
我們將創(chuàng)建兩個(gè)實(shí)體類 Order
和 OrderItem
,并在 Order
類中添加一個(gè)字符串屬性 OrderItemsJson
來(lái)保存 JSON 格式的訂單項(xiàng)數(shù)據(jù)。
using System;
using System.Collections.Generic;
using Newtonsoft.Json; // 需要安裝 NuGet 包:Newtonsoft.Json
public class Order
{
public int OrderId { get; set; }
public int CustomerId { get; set; }
public DateTime OrderDate { get; set; }
public string OrderItemsJson { get; set; } // 存儲(chǔ)訂單項(xiàng)的 JSON 字符串
}
public class OrderItem
{
public int OrderItemId { get; set; }
public int ProductId { get; set; }
public int Quantity { get; set; }
public decimal UnitPrice { get; set; }
}
2.2 創(chuàng)建數(shù)據(jù)示例并序列化為JSON
我們將創(chuàng)建一個(gè)包含訂單和訂單項(xiàng)的示例,并將這些訂單項(xiàng)序列化為JSON字符串。
class Program
{
static void Main(string[] args)
{
// 創(chuàng)建示例訂單和訂單項(xiàng)
Order order = new Order
{
OrderId = 1,
CustomerId = 123,
OrderDate = DateTime.Now,
OrderItemsJson = SerializeOrderItems(new List<OrderItem>
{
new OrderItem{ OrderItemId = 1, ProductId = 456, Quantity = 2, UnitPrice = 12.50m },
new OrderItem{ OrderItemId = 2, ProductId = 789, Quantity = 3, UnitPrice = 15.00m }
})
};
// 顯示結(jié)果
Console.WriteLine("訂單ID: " + order.OrderId);
Console.WriteLine("客戶ID: " + order.CustomerId);
Console.WriteLine("訂單日期: " + order.OrderDate);
Console.WriteLine("訂單項(xiàng)JSON: " + order.OrderItemsJson);
}
// 序列化訂單項(xiàng)
static string SerializeOrderItems(List<OrderItem> orderItems)
{
return JsonConvert.SerializeObject(orderItems);
}
}
2.3 保存到數(shù)據(jù)庫(kù)
在實(shí)際應(yīng)用中,我們會(huì)將訂單數(shù)據(jù)保存到數(shù)據(jù)庫(kù)中。以EF Core為例,我們可以簡(jiǎn)單地將Order
對(duì)象保存到數(shù)據(jù)庫(kù)中。
Install-Package Microsoft.EntityFrameworkCore
Install-Package Microsoft.EntityFrameworkCore.Sqlite
Install-Package SQLitePCLRaw.bundle_e_sqlite3
using Microsoft.EntityFrameworkCore;
public class ApplicationDbContext : DbContext
{
public DbSet<Order> Orders { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlite("Data Source=orders.db"); // 配置數(shù)據(jù)庫(kù)連接
}
}
// 示例保存過(guò)程
static void SaveOrderToDatabase(Order order)
{
using (var context = new ApplicationDbContext())
{
context.Database.EnsureCreated();
context.Orders.Add(order);
context.SaveChanges();
}
}
class Program
{
static void Main(string[] args)
{
// 初始化SQLite庫(kù)
Batteries.Init();
// 創(chuàng)建示例訂單和訂單項(xiàng)
Order order = new Order
{
OrderId = 1,
CustomerId = 123,
OrderDate = DateTime.Now,
OrderItemsJson = SerializeOrderItems(new List<OrderItem>
{
new OrderItem{ OrderItemId = 1, ProductId = 456, Quantity = 2, UnitPrice = 12.50m },
new OrderItem{ OrderItemId = 2, ProductId = 789, Quantity = 3, UnitPrice = 15.00m }
})
};
// 保存訂單到數(shù)據(jù)庫(kù)
SaveOrderToDatabase(order);
}
static string SerializeOrderItems(List<OrderItem> orderItems)
{
return JsonConvert.SerializeObject(orderItems);
}
}
2.4 從數(shù)據(jù)庫(kù)讀取并反序列化
從數(shù)據(jù)庫(kù)讀取訂單時(shí),可以通過(guò)反序列化 OrderItemsJson
字段來(lái)恢復(fù)訂單項(xiàng)對(duì)象列表。
static Order ReadOrderFromDatabase(int orderId)
{
using (var context = new ApplicationDbContext())
{
return context.Orders.Find(orderId);
}
}
static List<OrderItem> DeserializeOrderItems(string orderItemsJson)
{
return JsonConvert.DeserializeObject<List<OrderItem>>(orderItemsJson);
}
class Program
{
static void Main(string[] args)
{
// 根據(jù)訂單ID讀取訂單
Order order = ReadOrderFromDatabase(1);
if (order != null)
{
List<OrderItem> orderItems = DeserializeOrderItems(order.OrderItemsJson);
Console.WriteLine("讀取到的訂單ID: " + order.OrderId);
Console.WriteLine("訂單項(xiàng)數(shù)量: " + orderItems.Count);
}
else
{
Console.WriteLine("訂單不存在.");
}
}
}
3. 總結(jié)
通過(guò)將子數(shù)據(jù)(如訂單項(xiàng))轉(zhuǎn)換為 JSON 字符串并保存到主數(shù)據(jù)表(如訂單)的一個(gè)字段中,我們可以簡(jiǎn)化數(shù)據(jù)庫(kù)的設(shè)計(jì)和操作。雖然這種方法在一定程度上降低了數(shù)據(jù)的規(guī)范化程度,但可以提升開(kāi)發(fā)效率并減少維護(hù)成本。在C#中,借助像 Newtonsoft.Json 這樣的庫(kù),我們可以輕松實(shí)現(xiàn)數(shù)據(jù)的序列化和反序列化操作,從而達(dá)到我們的目的。
該文章在 2024/8/19 18:29:39 編輯過(guò)