2010-09-03 21 views
10

Tôi đang cố gắng tạo động một cây biểu thức trong C#, được biên dịch và được sử dụng làm vị từ cho lời gọi LINQ-to-SQL Where(). Vấn đề là tôi đang cố gắng so sánh một Enum (với int là kiểu cơ bản của nó) trực tiếp chống lại một Int, nhưng điều này không thành công với lỗi "Thành viên MyEnumType không có bản dịch được hỗ trợ cho SQL".Làm cách nào để chuyển đổi một Enum thành Int để sử dụng trong một hoạt động Expression.Equals?

Code:

ParameterExpression param = Expression.Parameter(typeof(MyClass), "obj"); //input parameter - this exposes a property of the Enum type 
MemberExpression enumMember = Expression.Property(param, "MyEnumProperty"); //used to get the Enum typed property from the parameter 

//MISSING STEP TO CAST THE ENUM OF THE MEMBER EXPRESSION TO AN INT? 

BinaryExpression binaryExpr = Expression.Equal(enumMember, Expression.Constant(1)); 
LambdaExpression<Func<MyClass, bool>> whereClause = Expression.Lambda(binaryExpr, param); 

//when whereClause is used to filter LINQ-to-SQL results, the error is thrown 

Tôi khá mới để cây biểu hiện và tôi không thể hình này ra. Tôi đã thử sử dụng

Expression.Convert(enumMember, typeof(int)) 

làm phần đầu tiên của BinaryExpression nhưng điều này không khắc phục được.

Bất kỳ trợ giúp nào được đánh giá cao.

+0

này không có ý tưởng về làm thế nào để nhận được giá trị của enum trong cây biểu –

+0

Sau khi một số digging hơn, tôi đã quyết định rằng vấn đề ở đây là với sự hiểu biết của tôi LINQ-to-SQL hơn với biểu thức chính nó. Thuộc tính Enum trên đối tượng thực thể của tôi không thực sự là một cột trong cơ sở dữ liệu; Tôi nghĩ rằng đây là lý do tại sao nó không thể dịch nó sang một mệnh đề where. Tôi sẽ thực hiện một cách tiếp cận khác nhưng nếu có ai có bất kỳ thông tin chi tiết nào, hãy chia sẻ. –

+0

Bạn cũng có thể cung cấp mã cho MyClass không? Mã bạn hiện đang có trong bài đăng khá sôi nổi, không nhiều để kể từ đây ... – code4life

Trả lời

0

Hãy thử

(int) enumMember 
+0

Điều này không biên dịch: "Không thể chuyển đổi loại 'System.Linq.Expressions.MemberExpression' thành 'int'" –

+0

Heh, Sjoerd sẽ là chính xác ... nếu * enumMember * là một enum thực tế và không phải là một biểu hiện cây trừu tượng của một. –

0

tìm bạn bè của tôi trước hết bạn phải thay đổi enum của bạn là như thế:

public enum myenum : int 
{ 
item1 = 0, 
item2 = 1 
} 

sau đó bạn có thể chuyển đổi giữa int và eunm bằng cách đó:

int x = (int) myenum.item1; 
+0

Câu trả lời này là một sự hiểu lầm rõ ràng về câu hỏi - OP muốn biết cách sử dụng các cây biểu thức để làm việc với các loại enum. Ngoài ra - enums là tự nhiên của loại 'int' trong CLR. Câu hỏi này là một hit tìm kiếm cao cho các biểu thức C# với enums và như vậy câu trả lời này nên thấp hơn câu trả lời phù hợp hơn từ @philsoady –

6

Đơn giản, bạn không cần phải, miễn là bạn đã nói LINQ-to-SQL về enum (chứ không phải là bản đồ ping nó dưới dạng int và có một tài sản riêng biệt trong C# thực hiện bản dịch). Ví dụ, sau đây hoạt động tốt:

var param = Expression.Parameter(typeof(DomainObject)); 
var body = Expression.Equal(Expression.Property(param, "SomeProperty"), 
         Expression.Constant(YourEnumType.SomeEnum)); 
var predicate = Expression.Lambda<Func<DomainObject, bool>>(body, param); 
var count = db.Table.Where(predicate).Count(); 

Điểm chính là tài sản của tôi SomeProperty được ánh xạ trong dbml để enum. Đơn giản chỉ cần overtype tên loại với kiểu enum (bao gồm cả không gian tên).

Tương tự như vậy, bạn không nên cho nó 1, mà đúng hơn là kiểu được nhập; ví dụ:

Expression.Constant(Enum.ToObject(typeof(YourEnumType), 1)) 

(nếu tất cả các bạn biết là 1)

1

Thanks To Marc Gravell. (Biểu hiện Guru!) Xem câu trả lời đúng. Tôi đã thực hiện thay đổi đối với Expression Routine để phục vụ cho kịch bản này. Thuộc tính thông thường hoặc Enums. Trong trường hợp ai đó tìm thấy hữu ích

public static Expression<Func<TPoco, bool>> GetEqualsPredicate<TPoco>(string propertyName, 
                      object value) 
                      Type fieldType) 
    {  

     var parameterExp = Expression.Parameter(typeof(TPoco), @"t"); //(tpoco t) 
     var propertyExp = Expression.Property(parameterExp, propertyName);// (tpoco t) => t.Propertyname 

     var someValue = fieldType.IsEnum // get and eXpressionConstant. Careful Enums must be reduced 
        ? Expression.Constant(Enum.ToObject(fieldType, value)) // Marc Gravell fix 
        : Expression.Constant(value, fieldType); 

     var equalsExp = Expression.Equal(propertyExp, someValue); // yes this could 1 unreadble state if embedding someValue determination 

     return Expression.Lambda<Func<TPoco, bool>>(equalsExp, parameterExp); 
    } 
Các vấn đề liên quan