Tôi đang triển khai một lớp đệm giữa cơ sở dữ liệu của tôi và mã C# của tôi. Ý tưởng là lưu trữ kết quả của một số truy vấn DB nhất định dựa trên các tham số cho truy vấn. Cơ sở dữ liệu đang sử dụng collation mặc định - hoặc SQL_Latin1_General_CP1_CI_AS
hoặc Latin1_General_CI_AS
, mà tôi tin rằng dựa trên một số googling ngắn gọn là tương đương cho bình đẳng, chỉ khác nhau để phân loại.Cái gì NET StringComparer tương đương với SQL1 của Latin1_General_CI_AS
Tôi cần một .NET StringComparer có thể cho tôi cùng một hành vi, ít nhất là để kiểm tra bình đẳng và tạo mã băm, khi đối chiếu của cơ sở dữ liệu đang sử dụng. Mục đích là để có thể sử dụng StringComparer trong một từ điển .NET trong mã C# để xác định xem một chuỗi khóa cụ thể đã có trong bộ nhớ cache hay chưa.
Một ví dụ thực sự đơn giản:
var comparer = StringComparer.??? // What goes here?
private static Dictionary<string, MyObject> cache =
new Dictionary<string, MyObject>(comparer);
public static MyObject GetObject(string key) {
if (cache.ContainsKey(key)) {
return cache[key].Clone();
} else {
// invoke SQL "select * from mytable where mykey = @mykey"
// with parameter @mykey set to key
MyObject result = // object constructed from the sql result
cache[key] = result;
return result.Clone();
}
}
public static void SaveObject(string key, MyObject obj) {
// invoke SQL "update mytable set ... where mykey = @mykey" etc
cache[key] = obj.Clone();
}
Lý do điều quan trọng là các StringComparer phù hợp đối chiếu của cơ sở dữ liệu là cả hai dương tính giả và âm tính giả sẽ có những ảnh hưởng xấu đối với các mã.
Nếu StringComparer nói rằng hai phím A và B bằng nhau khi cơ sở dữ liệu tin rằng chúng khác nhau, thì có thể có hai hàng trong cơ sở dữ liệu với hai khóa đó, nhưng bộ nhớ cache sẽ ngăn chặn thứ hai. yêu cầu cho A và B liên tiếp - bởi vì nhận được cho B sẽ không chính xác nhấn bộ nhớ cache và trả lại đối tượng đã được lấy cho A.
Vấn đề là tinh tế hơn nếu StringComparer nói rằng A và B là khác nhau khi cơ sở dữ liệu tin rằng chúng bình đẳng, nhưng không kém phần nào. Các cuộc gọi GetObject cho cả hai phím sẽ là tốt và trả về các đối tượng tương ứng với cùng một hàng cơ sở dữ liệu. Nhưng sau đó gọi SaveObject với khóa A sẽ để lại bộ nhớ cache không chính xác; vẫn sẽ có một mục nhập bộ nhớ cache cho khóa B có dữ liệu cũ. Một GetObject tiếp theo (B) sẽ cung cấp thông tin lỗi thời.
Vì vậy, để mã của tôi hoạt động chính xác, tôi cần StringComparer để phù hợp với hành vi của cơ sở dữ liệu để kiểm tra bình đẳng và tạo mã băm. Việc googling của tôi cho đến nay đã mang lại rất nhiều thông tin về thực tế rằng các đối chiếu SQL và so sánh .NET không chính xác tương đương, nhưng không có chi tiết về sự khác biệt là gì, cho dù chúng chỉ giới hạn trong các phân loại hoặc liệu có thể tìm thấy một StringComparer tương đương với cụ thể SQL collation nếu không cần một giải pháp đa năng.
(Lưu ý bên cạnh - lớp lưu trong bộ nhớ cache là mục đích chung, vì vậy tôi không thể đưa ra các giả định cụ thể về bản chất của khóa đó là gì và collation nào là phù hợp. Tất cả các bảng trong cơ sở dữ liệu của tôi đều chia sẻ cùng một máy chủ mặc định. chỉ cần khớp với đối chiếu khi nó tồn tại)
Thật không may IComparer không bao gồm khả năng nhận mã băm - tôi cần IEqualityComparer, cái mà StringComparer cung cấp. – Stuart
@Stuart - Xem bản chỉnh sửa của tôi, CollactionInfo không có IEqualityComparer. – dana
Có cách nào để đạt được tương đương .NET SQL_Latin1_General_CP1_CI_AS bằng cách (chỉ đơn giản) cấu hình hoặc triển khai một kiểu cơ bản không? SMO là một sự phụ thuộc nặng nề cho tình hình của tôi. –