2009-12-28 26 views
6

Tôi đang tạo một wiki cộng đồng này, vì tôi sẽ đánh giá cao cách tiếp cận của mọi người và không nhất thiết là câu trả lời.Enums hoặc Tables?

Tôi đang ở trong tình huống mà tôi có nhiều trường dữ liệu kiểu tra cứu, không thay đổi. Một ví dụ sẽ là:

hàng năm Mức lương
Tùy chọn: 0 - 25K
Tùy chọn: 25K - 100K
Tùy chọn: 100K +

Tôi muốn có các tùy chọn dễ dàng có sẵn thông qua một enum, nhưng cũng muốn các giá trị văn bản có sẵn trong DB, như tôi sẽ làm báo cáo về các giá trị văn bản và không phải là một ID. Ngoài ra, vì chúng tĩnh nên tôi không muốn thực hiện cuộc gọi đến DB.

Tôi đã suy nghĩ sao chép điều này trong một cái bàn và cái bàn, nhưng muốn nghe một số suy nghĩ thay thế.

Cảm ơn

Trả lời

7

Tôi nghĩ rằng enum là một ý tưởng tồi. Chỉ cần cho loại dữ liệu bạn hiển thị, nó có thể thay đổi. Tốt hơn để có một bảng cơ sở dữ liệu với các trường ID/Min/Max/Mô tả mà bạn tải khi ứng dụng của bạn khởi chạy.

+0

Đó là một ví dụ, nó sẽ không thay đổi. Tôi thích cách tiếp cận của bạn, làm thế nào bạn sẽ tồn tại dữ liệu trong suốt ứng dụng. Sẽ có bất kỳ vấn đề hiệu suất nào là dữ liệu không cần thiết cho 99% ứng dụng? –

+1

Nếu dữ liệu này hiếm khi được truy cập, bạn chỉ có thể giữ nó trong một lớp tĩnh được khởi tạo lần đầu tiên bạn yêu cầu dữ liệu (khởi tạo lười). Chỉ cần đảm bảo rằng các khóa được đặt đúng chỗ để chỉ một luồng có thể truy cập dữ liệu đó tại một thời điểm. Điều này sẽ loại bỏ bất kỳ sự khởi động chậm chạp nào. Nếu bạn không muốn đợi lần đầu tiên truy cập dữ liệu, bạn cũng có thể thêm tải dữ liệu vào hàng đợi công việc có mức độ ưu tiên thấp để được tải khi không hoạt động trong một hoặc hai khoảnh khắc (hoặc được tải ngay nếu cần) – Eclipse

+2

Nếu nó thực sự không thay đổi và bạn không có cơ sở dữ liệu, bạn có thể lưu trữ nó trong tệp app.config trong phần tùy chỉnh. –

1

Tôi sử dụng cả hai. Trong LINQ to SQL và EF, bạn chỉ cần tạo thuộc tính cột là kiểu enum. Trong các khung công tác khác, bạn có thể thường ánh xạ cột tới một thuộc tính enum bằng cách nào đó. Bạn vẫn có thể có một bảng khóa chính trong cơ sở dữ liệu chứa các enums hợp lệ. Bạn cũng có thể làm điều này với một ràng buộc CHECK trong cơ sở dữ liệu, nhưng điều đó có xu hướng buộc dữ liệu của bạn vào ứng dụng của bạn - ai đó nhìn vào cơ sở dữ liệu một mình sẽ không nhất thiết phải biết ý nghĩa của từng giá trị. Vì vậy, tôi thích bảng lai/enum.

0

Trước tiên hãy đảm bảo dữ liệu này thực sự tĩnh. Nếu bất cứ điều gì thay đổi, bạn sẽ phải biên dịch lại và triển khai lại.

Nếu dữ liệu thực sự tĩnh, tôi sẽ đi đến tuyến đường enum. Bạn có thể tạo YearlySalaryEnum giữ tất cả các giá trị. Đối với biểu diễn chuỗi, tôi sẽ sử dụng từ điển có giá trị chuỗi và YearlySalaryEnum làm Khóa. Từ điển có thể được giữ như một thể hiện tĩnh trong một lớp tĩnh. Cách sử dụng sẽ là dọc theo dòng của (C#):

string highSalary = StaticValues.Salaries[YearlySalaryEnum.High]; 
+0

Còn về báo cáo SQL thì sao? Làm thế nào mà sẽ được giải quyết bằng cách sử dụng một cách tiếp cận enum chỉ. –

+1

Khởi tạo từ điển từ DB, khá dễ dàng. Nếu kiểu dữ liệu đằng sau enum là một số nguyên, ánh xạ nó tới một cột db là đơn giản. Như Aaron đã chỉ ra, nhiều ORM có thể làm như vậy ra khỏi hộp. –

-1

Sử dụng cả enum (mã) và DB texts- để trình bày GUI. Vì vậy, nếu bạn sẽ luôn có 3 tùy chọn, hãy sử dụng enum LowSalary, MiddleSalaryHighSalary, lưu trữ văn bản của bạn trong DB và chuyển văn bản của bạn trong GUI tương ứng với giá trị enum thuộc tính của bạn.

1

Sử dụng cả hai, Và bạn nên điều tra CodeDOM. bằng cách sử dụng điều này, bạn có thể viết các thói quen tạo mã cho phép quá trình biên dịch tự động tạo ra một assembly hoặc lớp với các enums này, bằng cách đọc cơ sở dữ liệu. Bằng cách này bạn có thể để cho ổ đĩa cơ sở dữ liệu, nhưng bạn không thực hiện cuộc gọi đến cơ sở dữ liệu mỗi khi bạn truy cập một thể hiện của enum ...

0

Vì C# không cho phép Enums có giá trị chuỗi nên tôi sẽ đề xuất struct với một số chuỗi tĩnh.

Bằng cách đó, bạn duy trì một số Intellisense, nhưng không cố gắng để shoehorn một giá trị Enum trên một giá trị chuỗi trong cơ sở dữ liệu là gì.

Giải pháp khác tôi cung cấp: loại bỏ logic phụ thuộc vào các giá trị này và chuyển sang logic dựa trên bảng. (Ví dụ, nếu mỗi vụ bẫy có thuế suất khác nhau, hãy thêm thuế suất làm cột trong cơ sở dữ liệu chứ không phải là một trường hợp {} trong mã.).

2

Một cách là viết một định dạng mà có thể biến bạn enum vào cơ quan đại diện chuỗi:

public class SalaryFormatter : IFormatProvider, ICustomFormatter 
{ 
    public object GetFormat(Type formatType) 
    { 
     return (formatType == typeof(ICustomFormatter)) ? new 
     SalaryFormatter() : null; 
    } 

    public string Format(string format, object o, IFormatProvider formatProvider) 
    { 
     if (o.GetType().Equals(typeof(Salary))) 
     { 
      return o.ToString(); 

      Salary salary = (Salary)o; 
      switch (salary) 
      { 
       case Salary.Low: 
        return "0 - 25K"; 
       case Salary.Mid: 
        return "25K - 100K"; 
       case Salary.High: 
        return "100K+"; 
       default: 
        return salary.ToString(); 
      } 
     } 

    return o.ToString(); 
    } 
} 

Bạn sử dụng các định dạng giống như bất kỳ định dạng khác:

Console.WriteLine(String.Format(new SalaryFormatter(), "Salary: {0}", salary)); 

Các định dạng có thể được extented để hỗ trợ các định dạng khác nhau thông qua các chuỗi định dạng, nhiều loại, bản địa hóa, v.v.

+0

tôi nghĩ rằng họ sẽ không đánh giá cao ý tưởng. Tôi không biết tại sao, nhưng có một bảng cơ sở dữ liệu cho 3 biến này được nhìn thấy tốt hơn bởi họ ... – serhio

1

Có xem xét đề nghị của tôi ở đây How to work with Enums in Entity Framework?

Về cơ bản tôi sử dụng các giá trị mặc định script sql cho dữ liệu tra cứu cốt lõi, với ID để tham khảo FK từ các bảng khác, và sau đó tôi sử dụng một mẫu T4 đơn giản để tạo ra sự đếm của tôi cho C#. Bằng cách đó, cơ sở dữ liệu là hiệu quả, bình thường và bị ràng buộc chính xác, và các thực thể C# của tôi không phải đối phó với các ID (số Magic).

Công việc đơn giản, nhanh chóng và dễ dàng của tôi đối với tôi.

Tôi sử dụng EF4, nhưng bạn không cần, có thể sử dụng phương pháp này với bất kỳ công nghệ nào bạn sử dụng cho các thực thể của mình.

6

Đối với các mục tĩnh tôi sử dụng Enum với thuộc tính [Description()] cho mỗi phần tử. Và mẫu T4 tái sinh enum thiệu về xây dựng (hoặc bất cứ khi nào bạn muốn)

public enum EnumSalary 
    { 
     [Description("0 - 25K")] Low, 
     [Description("25K - 100K")] Mid, 
     [Description("100K+")] High 
    } 

Và sử dụng nó như

string str = EnumSalary.Mid.Description() 

T.B. cũng tạo ra phần mở rộng cho System.Enum

public static string Description(this Enum value) { 
    FieldInfo fi = value.GetType().GetField(value.ToString()); 
    var attributes = (DescriptionAttribute[]) fi.GetCustomAttributes(typeof(DescriptionAttribute), false); 
    return attributes.Length > 0 ? attributes[0].Description : value.ToString(); 
} 

và đảo ngược để tạo ra enum bởi mô tả

public static TEnum ToDescriptionEnum<TEnum>(this string description) 
{ 
    Type enumType = typeof(TEnum); 
    foreach (string name in Enum.GetNames(enumType)) 
    { 
     var enValue = Enum.Parse(enumType, name); 
     if (Description((Enum)enValue).Equals(description)) { 
      return (TEnum) enValue; 
     } 
    } 
    throw new TargetException("The string is not a description or value of the specified enum."); 
}