2011-09-13 26 views
5

Tôi có câu hỏi kiến ​​trúc liên quan đến trường tùy chỉnh trong chế độ xem cho một đối tượng. Giả sử bạn có một đối tượng người dùng với một số thông tin cơ bản như firstname, lastname, ... có thể được tất cả các khách hàng sử dụng.Trường tùy chỉnh cho Biểu mẫu đại diện cho một đối tượng

Hiện tại, chúng tôi thường nhận được câu hỏi từ khách hàng để thêm một vài trường tùy chỉnh điển hình cho miền của họ. Giải pháp của chúng tôi bây giờ là cột dữ liệu xml, nơi các cặp giá trị khóa được lưu trữ. Điều này đã được ok cho đến nay, nhưng bây giờ chúng ta sẽ phải tìm một giải pháp kiến ​​trúc hơn.

Ví dụ: hiện tại, khách hàng muốn có danh sách thả xuống nơi khách hàng có thể chọn giá trị cho trường tùy chỉnh của mình. Chúng tôi vẫn có thể lưu trữ giá trị đã chọn trong cột dữ liệu xml, nhưng chúng tôi lưu trữ tất cả các giá trị thả xuống đó ở đâu ...

Tôi biết rằng bạn càng có thể thêm các trường tùy chỉnh như trình đơn thả xuống và tôi đã tự hỏi cách xử lý điều này tốt nhất. Tôi muốn tránh tạo bảng tùy chỉnh cho khách hàng hoặc có một bảng với 90 cột (10 cơ bản và sau đó là 10 cho mỗi khách hàng), ...

Bạn nên có khái niệm chung và có thể giải quyết tất cả các loại vấn đề trong tương lai.

Điều tôi đang nghĩ đến là Bảng cấu hình người dùng trong đó mỗi bản ghi có khóa ngoại cho khách hàng (kênh trong cơ sở dữ liệu của chúng tôi), sau đó là một trường FieldName, cột FieldType và giá trị cột. Giá trị cột phải là cột loại xml, vì đối với một menu thả xuống, chúng tôi sẽ cần phải thêm nhiều giá trị. Ngoài ra, mỗi giá trị có thể có thêm dữ liệu gắn liền với nó (không chỉ là một tên). Vấn đề khác sau đó là làm thế nào để lưu trữ giá trị đã chọn. Tôi không thích ý tưởng có chìa khóa nước ngoài để xml trong cơ sở dữ liệu của tôi (đọc một nơi nào đó mà Azure không thể xử lý tất cả điều này là tốt). Bạn chỉ cần lưu trữ tên của giá trị (nếu giá trị đã biến mất khỏi xml?)?

Mọi tài liệu, liên kết về loại vấn đề này cũng sẽ tuyệt vời. Tôi đang cố gắng để tìm một mẫu thiết kế mà đề với loại vấn đề trong cơ sở dữ liệu.

+0

Nếu đây là chủ đề, thì bạn không phải là lập trình viên thực tế. –

+1

Bạn đã thấy điều này trên SO: http://stackoverflow.com/questions/1126783/what-are-design-patterns-to-support-custom-fields-in-an-application? Nó có vẻ khá toàn diện đối tượng. –

+0

@Simon Thx, chưa tìm thấy cái đó. –

Trả lời

4

tôi muốn trả lời câu hỏi của bạn thành hai phần:
1) Thực hiện các lĩnh vực tùy chỉnh trong một máy chủ cơ sở dữ liệu
2) Hạn chế các lĩnh vực tùy chỉnh cho một liệt kê các giá trị


Mặc dù các giải pháp phổ biến cho 1) được thảo luận trong số question được tham chiếu bởi @Simon, có thể bạn đang tìm kiếm một chút thảo luận về vấn đề là gì và tại sao nó chưa được giải quyết cho chúng tôi.

  • cơ sở dữ liệu là tuyệt vời cho cấu trúc, gõ sẽ dữ liệu
  • lĩnh vực tùy chỉnh vốn đã ít có cấu trúc
  • do đó, các lĩnh vực tùy chỉnh là khó khăn hơn để làm việc với một cơ sở dữ liệu
  • một số hoặc nhiều trong những lợi thế của việc sử dụng cơ sở dữ liệu bị mất
    • một số truy vấn có thể khó khăn hơn hoặc không thể
    • loại an toàn có thể bị mất (trong cơ sở dữ liệu)
    • toàn vẹn dữ liệu có thể không còn được áp dụng (theo cơ sở dữ liệu)
    • nó làm việc nhiều hơn nữa cho những người thực hiện và bảo trì

Như đã thảo luận trong other question, không có giải pháp hoàn hảo.
Nhưng những lợi ích/tính năng này vẫn cần được triển khai ở đâu đó và do đó, ứng dụng thường xuyên chịu trách nhiệm về tính toàn vẹn dữ liệu và an toàn loại.
Đối với các tình huống như thế này, mọi người đã tạo ra Object-Relation Mapping tools, mặc dù, như Jeff Atwood says, thậm chí sử dụng ORM cũng có thể tạo ra nhiều vấn đề hơn giải pháp. Tuy nhiên, bạn đã đề cập rằng nó 'phải là chung chung và có thể đối phó với tất cả các loại vấn đề trong tương lai' - điều này làm cho tôi nghĩ rằng một ORM có thể là đặt cược tốt nhất của bạn.

Vì vậy, để tổng hợp câu trả lời của tôi, đây là một vấn đề đã biết với các giải pháp đã biết, không có giải pháp nào hoàn toàn thỏa đáng (vì nó quá khó). Chọn thuốc độc của bạn.


Để trả lời phần thứ hai của (những gì tôi nghĩ là) câu hỏi của bạn:
Như đã đề cập trong câu hỏi liên kết, bạn có thể thực hiện Entity-Attribute-Value trong cơ sở dữ liệu của bạn cho các lĩnh vực tùy chỉnh, và sau đó thêm một bảng phụ để giữ các giá trị pháp lý cho mỗi thực thể. Sau đó, thuộc tính/giá trị của bảng EAV là khóa ngoài vào bảng thuộc tính-giá trị.

Ví dụ,

CREATE TABLE `attribute_value` (-- enumerations go in this table 
    `attribute` varchar(30), 
    `value` varchar(30), 
    PRIMARY KEY (`attribute`, `value`) 
); 

CREATE TABLE `eav` (-- now the values of attributes are restricted 
    `entityid` int, 
    `attribute` varchar(30), 
    `value` varchar(30), 
    PRIMARY KEY (`entityid`, `attribute`), 
    FOREIGN KEY (`attribute`, `value`) REFERENCES `attribute_value`(`attribute`, `value`) 
); 

Tất nhiên, giải pháp này không phải là hoàn hảo hay hoàn chỉnh - nó chỉ giả để minh họa cho ý tưởng. Ví dụ, nó sử dụng varchars, và thiếu một cột type. Ngoài ra, ai sẽ quyết định giá trị có thể có cho từng thuộc tính là gì? Những điều này có thể được thay đổi bất kỳ lúc nào bởi người dùng không?

2

Tôi đang làm điều gì đó tương tự cho khách hàng. Tôi đã tạo một JSON FieldType chứa toàn bộ luồng JSON của một đối tượng phức tạp và một String chứa FQTN (FullQualifiedTypeName) của lớp mô hình C# của tôi.

Bằng cách sử dụng các biểu mẫu tùy chỉnh mới, chỉnh sửa và hiển thị, chúng tôi đảm bảo rằng các đối tượng tùy chỉnh của chúng tôi được hiển thị đúng cách để có trải nghiệm người dùng tốt nhất.

Để quảng bá các trường từ mô hình C# phức tạp vào danh sách SharePoint, chúng tôi đã tạo một thứ giống như Microsoft đã làm trong InfoPath. Người dùng có thể chọn Thuộc tính hoặc MetaData từ loại C# phức tạp, sẽ được tự động thăng hạng lên danh sách SharePoint lưu trữ.

Ưu điểm lớn của JSON là, nó nhỏ hơn XML và dễ làm việc hơn trong thế giới web. (JavaScript ...)

2

Khi bạn cho phép người dùng tạo mô hình dữ liệu, tôi khuyên bạn nên xem xét cơ sở dữ liệu tài liệu hoặc 'NoSQL' vì bạn muốn chính xác điều đó, để lưu trữ cấu trúc dữ liệu schemaless.

Ngoài ra, các cửa hàng SharePoint siêu dữ liệu theo cách bạn đề cập (10 cột cho văn bản, 5 cho những ngày vv)

Điều đó nói rằng, trong dự án hiện tại của tôi (bị khóa trong SharePoint, vì vậy Khung 3.5 + SQL Server và tất cả các khó khăn mà làm theo), chúng tôi sử dụng một cấu trúc phần nào tương tự như dưới đây:

Form 
Id 

Attribute (or Field) 
Name 
Type (enum) Text, List, Dates, Formulas etc 
Hidden (bool) 
Mandatory 
DefaultValue 
Options (for lists) 
Readonly 
Mask (for SSN etc) 
Length (for text fields) 
Order 

Metadata 
FormId 
AttributeId 
Text (the value for everything but dates) 
Date (the value for dates) 

công thức của chúng tôi sử dụng các chức năng như Tăng: INC([attribute1][attribute2], 6) và điều này sẽ tạo ra một cái gì đó giống như 000.999 cho Ví dụ 999 của kết hợp giá trị cho thuộc tính 1 và thuộc tính 2 cho một hình thức, điều này được lưu giữ như:

AttributeIncrementFormula 
AtributeId 
Counter 
Token 

khác 'công thức' (aka bất cứ điều gì không tầm thường) như mã vạch được lưu trữ như các giá trị siêu dữ liệu duy nhất. Trong việc thực hiện thực tế, chúng ta sẽ có một cái gì đó như thế này:

var form = formRepository.GetById(1); 
form.Metadata["firstname"].Value 

Giá trị trên là một tài sản readonly rằng quyết định liệu chúng ta nên có được giá trị từ văn bản hoặc ngày và nếu một số bổ sung chuyển đổi là bắt buộc. Lưu ý rằng cơ sở dữ liệu ở đây chỉ là một lưu trữ, chúng tôi giữ tất cả sự phức tạp của miền trong ứng dụng.

Chúng tôi cũng cho phép khách hàng quyết định thuộc tính nào là tiêu đề biểu mẫu, vì vậy nếu firstname là tiêu đề biểu mẫu, họ sẽ đặt tham số trong bộ nhớ mở rộng toàn bộ ứng dụng thành Params.InMemory.TitleAttributeId = <user-defined-id>.

Tôi hy vọng điều này sẽ cung cấp cho bạn một số thông tin chi tiết về quy trình sản xuất của một kịch bản tương tự.

2

Đây thực sự là nhiều hơn một bình luận hơn là một câu trả lời, nhưng tôi cần nhiều không gian hơn SO sẽ cho phép để lấy ý kiến, vì vậy đây 'Tis:

Tôi nghĩ rằng cách tiếp cận bảng UserConfiguration của bạn là tốt, và sẽ chỉ đề nghị trừu tượng hóa các "type" và "giá trị" mẩu thiết kế của bạn nhiều hơn một chút:

  • Kể từ khi ứng dụng của bạn sẽ cần phải xác nhận đầu vào người dùng, mỗi khái niệm "loại" sẽ có một mảnh liên quan đến logic đánh giá. Rõ ràng là bạn càng có thể tóm tắt dữ liệu này vào dữ liệu càng dễ dàng để giữ cho mã của bạn nhỏ hơn. Danh sách liệt kê là một khởi đầu tốt, nhưng nếu logic "validator" của bạn có thể được mở rộng để xử lý khớp mẫu cho chuỗi văn bản và biểu thức logic Boolean (ví dụ: để mô tả/thực thi ràng buộc về giá trị đầu vào), thì bạn có thể thể hiện khá nhiều "loại" của đầu vào mà ứng dụng của bạn có thể cần xử lý theo các nguyên tử "tương đối" đơn giản mà bạn có thể ánh xạ tự nhiên đến các bảng DB.

  • Khi lưu trữ giá trị do người dùng chỉ định, bạn có thể lưu trữ dữ liệu "thô" (ví dụ như trong JSON) và khóa ngoại vào "loại" được liên kết hoặc bạn có thể thêm hệ thống tra cứu/bộ nhớ cache số nguyên cho mỗi giá trị mới mà hệ thống gặp phải ("mới lạ" có thể được kiểm tra bằng cách kiểm tra hàm băm của dữ liệu "thô"). Cách tiếp cận thứ hai rõ ràng là tốt hơn nếu bạn đang mong đợi rất nhiều dữ liệu trùng lặp (tất nhiên bạn sẽ có trong trường hợp của một menu đa lựa chọn).

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