2011-07-27 28 views
17

Tôi đang thử nghiệm với PetaPoco để chuyển đổi bảng thành POCO.PetaPoco có xử lý enums không?

Trong bảng của tôi, tôi có một cột có tên là TheEnum. Các giá trị trong cột này là chuỗi đại diện cho enum sau:

public enum MyEnum 
{ 
    Fred, 
    Wilma 
} 

PetaPoco nghẹn khi nó cố gắng để chuyển đổi chuỗi "Fred" thành một giá trị MyEnum.

Nó làm điều này trong phương pháp GetConverter, trong dòng:

Convert.ChangeType(src, dstType, null); 

Ở đây, src là "Fred" (một string), và dstTypetypeof(MyEnum).

Trường hợp ngoại lệ là một InvalidCastException, nói Invalid cast from 'System.String' to 'MyEnum'

Tôi có thiếu cái gì? Có điều gì tôi cần phải đăng ký trước?

Tôi đã có xung quanh vấn đề bằng cách thêm đoạn mã sau vào phương pháp GetConverter:

if (dstType.IsEnum && srcType == typeof(string)) 
{ 
    converter = delegate(object src) 
      { 
       return Enum.Parse(dstType, (string)src) ; 
      } ; 
} 

Rõ ràng, tôi không muốn chạy delegate này trên mỗi hàng vì nó sẽ làm chậm điều xuống rất nhiều. Tôi có thể đăng ký enum này và các giá trị của nó vào một từ điển để tăng tốc mọi thứ, nhưng có vẻ như với tôi rằng một cái gì đó như thế này có thể đã có trong sản phẩm.

Vì vậy, câu hỏi của tôi là, tôi có cần phải làm bất cứ điều gì đặc biệt để đăng ký enums của tôi với PetaPoco không?

Cập nhật ngày 23 Tháng Hai 2012

tôi submitted a patch một thời gian trước, nhưng nó đã không được kéo vào được nêu ra. Nếu bạn muốn sử dụng nó, hãy xem bản vá và nhập vào mã của riêng bạn hoặc chỉ nhận mã from here.

+0

** Cập nhật ngày 28 tháng 6 năm 2012 ** bản vá chính xác vẫn chưa được áp dụng nhưng mã tương tự đã được thêm vào [chi nhánh v5] (https://github.com/toptensoftware/PetaPoco/tree/v5). Xem thêm http://www.toptensoftware.com/Articles/137/Long-Time-No-Post-and-PetaPoco-v5 –

+0

Nếu nó không phải là khó khăn cho bạn, xin gửi bản vá cho npoco quá. Tôi khuyên bạn nên chuyển sang npoco, vì nó có sự phát triển tích cực hơn và có tất cả các tính năng mà PetaPoco có và thậm chí nhiều hơn nữa. – AuthorProxy

+0

** Cập nhật ngày 9 tháng 9 năm 2014 ** @iano answer là phiên bản chính xác cho phiên bản ** 5.0.2 ** mới nhất. –

Trả lời

5

Bạn nói đúng, xử lý enums không được tích hợp vào PetaPoco và thông thường tôi chỉ đề xuất thực hiện chính xác những gì bạn đã làm.

Lưu ý rằng thao tác này sẽ không làm chậm các yêu cầu không sử dụng loại enum. PetaPoco tạo ra mã để phản ánh bản đồ cho pocos để đại biểu sẽ chỉ được gọi khi thực sự cần thiết. Nói cách khác, các GetConverter sẽ chỉ được gọi là lần đầu tiên một loại poco cụ thể được sử dụng, và các đại biểu sẽ chỉ được gọi khi một enum cần chuyển đổi. Không chắc chắn về tốc độ của Enum.Parse, nhưng có bạn có thể cache trong một từ điển nếu nó quá chậm.

+0

Cảm ơn Brad. Tôi sẽ thêm tra cứu enum và gửi một bản vá. –

+0

Theo ngày 27 tháng 12 năm 2011, bản vá chưa được áp dụng. Nó sẽ là một bổ sung tốt đẹp. – JCallico

+0

** Cập nhật ngày 28 tháng 6 năm 2012 ** bản vá chính xác vẫn chưa được áp dụng nhưng mã tương tự đã được thêm vào [chi nhánh v5] (https://github.com/toptensoftware/PetaPoco/tree/v5). Xem thêm http://www.toptensoftware.com/Articles/137/Long-Time-No-Post-and-PetaPoco-v5 –

5

Tôi đang sử dụng 4.0.3 và PetaPoco tự động chuyển đổi enums thành số nguyên và ngược lại. Tuy nhiên, tôi muốn chuyển đổi enums của tôi thành chuỗi và ngược lại. Tận dụng lợi thế của Steve Dunn's EnumMapper và PetaPoco's IMapper, tôi đã nghĩ ra điều này. Cảm ơn các bạn.

Lưu ý rằng nó không xử lý các giá trị Nullable<TEnum> hoặc null trong DB. Để sử dụng nó, thiết lập PetaPoco.Database.Mapper = new MyMapper();

class MyMapper : PetaPoco.IMapper 
{ 
    static EnumMapper enumMapper = new EnumMapper(); 

    public void GetTableInfo(Type t, PetaPoco.TableInfo ti) 
    { 
     // pass-through implementation 
    } 

    public bool MapPropertyToColumn(System.Reflection.PropertyInfo pi, ref string columnName, ref bool resultColumn) 
    { 
     // pass-through implementation 
     return true; 
    } 

    public Func<object, object> GetFromDbConverter(System.Reflection.PropertyInfo pi, Type SourceType) 
    { 
     if (pi.PropertyType.IsEnum) 
     { 
      return dbObj => 
      { 
       string dbString = dbObj.ToString(); 
       return enumMapper.EnumFromString(pi.PropertyType, dbString); 
      }; 
     } 

     return null; 
    } 

    public Func<object, object> GetToDbConverter(Type SourceType) 
    { 
     if (SourceType.IsEnum) 
     { 
      return enumVal => 
      { 
       string enumString = enumMapper.StringFromEnum(enumVal); 
       return enumString; 
      }; 
     } 

     return null; 
    } 
} 
5

Nếu bạn đang sử dụng hệ T4 PetaPoco và bạn muốn enums trong loại được tạo ra, bạn có thể sử dụng ghi đè PropertyType trong cơ sở dữ liệu.tt:

tables["App"]["Type"].PropertyType = "Full.Namespace.To.AppType"; 
+0

Rất hữu ích. Cảm ơn! –

0

tôi bạn muốn để lưu trữ các giá trị của enum thay cho số chỉ mục (1,2,4 chẳng hạn), bạn có thể xác định vị trí chức năng cập nhật trong lớp PetaPoco vì mã là "quản lý" vv , khi bạn thêm nó như gói nuget, nó sẽ lưu trữ tệp .cs vào dự án của bạn. Nếu chúng ta sẽ có biến enum Màu = {đỏ, vàng, xanh dương}

Thay vì:

// Store the parameter in the command 
AddParam(cmd, pc.GetValue(poco), pc.PropertyInfo); 

thay đổi:

//enum? 
if (i.Value.PropertyInfo.PropertyType.IsEnum) 
{ 
     AddParam(cmd, i.Value.GetValue(poco).ToString(), i.Value.PropertyInfo); 
} 
else 
{ 
     // Store the parameter in the command 
     AddParam(cmd, i.Value.GetValue(poco), i.Value.PropertyInfo); 
} 

Nó sẽ lưu trữ "vàng" thay vì 2

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