2011-08-26 40 views
5

Tình huống là tôi có một bảng mô hình một thực thể. Thực thể này có một số thuộc tính (được xác định bởi một cột trong bảng). Vấn đề là trong tương lai tôi cần phải thêm các thuộc tính mới hoặc loại bỏ một số thuộc tính. Vấn đề là làm thế nào để mô hình hóa cả hai cơ sở dữ liệu và mã tương ứng (sử dụng C#) để khi một dịp như vậy xuất hiện nó sẽ rất dễ dàng để chỉ "có" một tài sản mới.Generics and database - một vấn đề thiết kế

Ban đầu chỉ có một thuộc tính để tôi có một cột. Tôi đã định nghĩa thuộc tính tương ứng trong lớp, với kiểu và tên thích hợp, sau đó tạo ra các thủ tục được lưu trữ để đọc nó và cập nhật nó. Sau đó, đến tài sản thứ hai, nhanh chóng sao chép-dán, thay đổi tên và loại và một chút của SQL và có nó được. Rõ ràng đây không phải là một mô hình phù hợp trong tương lai. Bởi thời gian này một số bạn có thể đề nghị một ORM (EF hoặc khác) bởi vì điều này sẽ tạo ra các mã SQL và tự động nhưng bây giờ đây không phải là một lựa chọn cho tôi.

Tôi nghĩ chỉ có một thủ tục để đọc một thuộc tính (theo tên thuộc tính) và một thủ tục khác để cập nhật nó (theo tên và giá trị), sau đó một số thủ tục chung để đọc một bó hoặc tất cả thuộc tính cho thực thể trong cùng một câu lệnh . Điều này nghe có vẻ dễ dàng trong C# nếu bạn xem xét sử dụng Generics nhưng cơ sở dữ liệu không biết Generics vì vậy nó không thể có một giải pháp đánh máy mạnh mẽ.

Tôi muốn có giải pháp "được đánh máy mạnh nhất có thể" nên tôi không cần phải thực hiện nhiều quá trình truyền và phân tích cú pháp. Tôi sẽ xác định các thuộc tính có sẵn trong mã, do đó bạn không đi đoán những gì bạn có sẵn và sử dụng các chuỗi ma thuật và những thứ tương tự. Sau đó, quá trình thêm thuộc tính mới vào hệ thống sẽ chỉ có nghĩa là thêm cột mới vào bảng và thêm thuộc tính "định nghĩa" mới vào mã (ví dụ: trong enum).

+0

Tại sao bạn không thể sử dụng EF? Các thiên tài tại Microsoft đã tìm ra và thực hiện rất nhiều công việc cho bạn trong lĩnh vực này. Tôi ghét phải thấy bạn tái phát minh ra bánh xe. – Jay

+0

Vâng, tôi không hiểu tại sao bạn cần phải tránh một ORM. (Ngoài ra, tôi không biết C# generics phải làm gì với bất kỳ điều này) –

+0

Tôi đồng ý nhưng EF ở xa hơn một chút so với con đường liên quan đến kiến ​​trúc nên tôi chưa thể sử dụng nó. – CyberDude

Trả lời

2

Có vẻ như bạn muốn làm điều này:

MyObj x = new MyObj(); 
x.SomeProperty = 10; 

Bạn có một bảng được tạo ra cho rằng, nhưng bạn không muốn giữ lại làm thay đổi bảng khi bạn thêm

x.AnotherProperty = "Some String"; 

Bạn cần phải chuẩn hóa dữ liệu bảng như vậy:

-> BaseTable 
    RecordId, Col1, Col2, Col3 

-> BaseTableProperty 
    PropertyId, Name 

-> BaseTableValue 
    ValueId, RecordId, PropertyId, Value 

Lớp học của bạn sẽ trông giống như vậy:

public class MyObj 
{ 
     public int Id { get; set; } 
     public int SomeProperty { get; set; } 
     public string AnotherProperty { get; set; } 
} 

Khi bạn tạo đối tượng từ DL, bạn liệt kê bộ bản ghi. Sau đó, bạn viết mã khi kiểm tra thuộc tính giống với tên cấu hình của bạn (BaseTableProperty.Name == MyObj.<PropertyName> - và sau đó thử loại truyền đến loại đó khi bạn liệt kê bộ bản ghi.

Sau đó, bạn chỉ cần thêm thuộc tính khác vào đối tượng của bạn, một kỷ lục cho cơ sở dữ liệu trong BaseTableProperty, và sau đó bạn có thể lưu trữ các giá trị cho anh chàng đó trong BaseTableValue

Ví dụ:.

RecordId 
======== 
1 

PropertyId   Name 
==========   ==== 
1     SomeProperty 

ValueId  RecordId  PropertyId  Value 
=======  ========  ==========  ===== 
1   1    1    100 

bạn có hai bộ kết quả, một cho dữ liệu cơ bản, và có ai tham gia từ bảng Thuộc tính và Giá trị.Khi bạn liệt kê từng bản ghi, bạn sẽ thấy Tên của SomeProperty - hiện typeof(MyObj).GetProperty("SomeProperty") có tồn tại không? Vâng? Nó là loại dữ liệu gì? int? Ok, sau đó thử chuyển đổi "100" thành int bằng cách đặt thuộc tính:

propertyInfo.SetValue(myNewObjInstance, Convert.ChangeType(dbValue, propertyInfo.PropertyType), null); 

Đối với mỗi thuộc tính.

+0

Đến gần nhưng tôi không thực sự muốn hoặc cần khai báo mỗi tài sản trong lớp. Nó hiếm khi xảy ra rằng tôi cần nhiều hơn một tài sản cùng một lúc. Hầu hết các lần tôi có ID đối tượng và chỉ cần biết một trong các thuộc tính. Đó là lý do tại sao tôi sẽ hướng tới phương thức 'GetProperty (int objectID, string propertyName)'. – CyberDude

+0

Tôi sẽ chấp nhận điều này vì đó là giải pháp gần nhất với giải pháp mà tôi sẽ thực hiện. – CyberDude

0

Thậm chí nếu bạn nói bạn không thể sử dụng chúng, đó là điều mà hầu hết ORM làm. Tùy thuộc vào bạn sử dụng (hoặc thậm chí tạo ra nếu đó là một kinh nghiệm học tập), họ sẽ rất khác nhau về sự phức tạp và hiệu suất. Nếu bạn thích ORM trọng lượng nhẹ, hãy kiểm tra Dapper.Net. Nó cũng sử dụng generics, vì vậy bạn có thể kiểm tra mã, xem nó hoạt động như thế nào và tạo ra giải pháp của riêng bạn nếu cần.

Các vấn đề liên quan