Một vài lần trong quá khứ tôi đã muốn lưu trữ dữ liệu bằng mã. Đây sẽ là dữ liệu hiếm khi thay đổi và được sử dụng ở những nơi không thể truy cập vào cơ sở dữ liệu, thực tế hoặc mong muốn. Một ví dụ nhỏ sẽ lưu trữ một danh sách các quốc gia. Cho rằng bạn có thể làm một cái gì đó như:
public class Country
{
public string Code { get; set; }
public string EnglishName {get;set;}
}
public static class CountryHelper
{
public static List<Country> Countries = new List<Country>
{
new Country {Code = "AU", EnglishName = "Australia"},
...
new Country {Code = "SE", EnglishName = "Sweden"},
...
};
public static Country GetByCode(string code)
{
return Countries.Single(c => c.Code == code);
}
}
Trước đây tôi đã từng làm điều này vì các bộ dữ liệu tương đối nhỏ và các đối tượng khá đơn giản. Bây giờ tôi đang làm việc với một cái gì đó sẽ có các đối tượng phức tạp hơn (mỗi thuộc tính 5 - 10, một số thuộc tính là từ điển) và tổng số khoảng 200 đối tượng.
Dữ liệu tự thay đổi rất hiếm khi và khi nó thay đổi, nó thực sự không quan trọng lắm. Vì vậy, đưa nó vào phiên bản phát hành tiếp theo là hoàn toàn tốt.
Tôi dự định sử dụng T4 hoặc ERB hoặc một số giải pháp tạo khuôn mẫu khác để biến nguồn dữ liệu của tôi thành thứ gì đó được lưu trữ tĩnh trong cụm.
Có vẻ như lựa chọn của tôi là
- Lưu trữ dữ liệu trong XML. Biên dịch tệp XML dưới dạng tài nguyên lắp ráp. Tải dữ liệu khi cần, lưu trữ dữ liệu đã tải vào Từ điển để sử dụng lại hiệu suất.
- Tạo một số loại đối tượng tĩnh hoặc các đối tượng được khởi tạo khi khởi động.
Tôi khá chắc chắn rằng tôi hiểu ý nghĩa hiệu suất của tùy chọn 1. Ít nhất, linh cảm của tôi là nó sẽ không có hiệu suất sao.
Đối với lựa chọn 2, tôi không biết phải làm gì. Tôi không biết đủ về các phần bên trong của .NET framework để biết cách tốt nhất để thực sự lưu trữ dữ liệu này trong mã C # và các cách tốt nhất để khởi tạo nó. Tôi đã sử dụng .NET Reflector để xem cách thức System.Globalization.CultureInfo.GetCulture(name)
hoạt động, vì đây thực sự là một quy trình công việc rất giống với những gì tôi muốn. Thật không may, con đường đó đã kết thúc tại một extern
, vì vậy không có gợi ý ở đó. Là khởi tạo một thuộc tính tĩnh với tất cả dữ liệu, như trong ví dụ của tôi, cách để đi? Hoặc sẽ tốt hơn để tạo các đối tượng theo yêu cầu và sau đó lưu trữ chúng, như thế này?
private static readonly Dictionary<string, Country> Cache = new Dictionary<string,Country>();
public static Country GetByCode(string code)
{
if (!Cache.ContainsKey(code))
return Cache[code];
return (Cache[code] = CreateCountry(code));
}
internal static Country CreateCountry(string code)
{
if (code == "AU")
return new Country {Code = "AU", EnglishName = "Australia"};
...
if (code == "SE")
return new Country {Code = "SE", EnglishName = "Sweden"};
...
throw new CountryNotFoundException();
}
Lợi thế để tạo chúng cùng một lúc trong một thành viên tĩnh là bạn có thể sử dụng LINQ hoặc bất cứ thứ gì khác để xem tất cả các đối tượng và truy vấn chúng nếu bạn muốn. Mặc dù tôi nghi ngờ làm điều này có một hình phạt hiệu suất khởi động. Tôi hy vọng ai đó có kinh nghiệm với điều này và có thể chia sẻ ý kiến của họ!