2010-09-03 47 views
10

我想在C#中動態構建一個表達式樹,它被編譯並用作LINQ-to-SQL Where()調用的謂詞。問題是,我試圖直接將一個Enum(使用int作爲它的基礎類型)與Int進行比較,但是這個失敗的錯誤是「成員MyEnumType沒有支持到SQL的轉換」。如何將Enum轉換爲Int以用於Expression.Equals操作?

代碼:

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 

我是相當新的表達式樹,我不明白這一點。我曾嘗試使用

Expression.Convert(enumMember, typeof(int)) 

作爲BinaryExpression的第一部分,但是這不能解決它。

任何幫助,非常感謝。

+0

沒有關於枚舉的表達式樹 – 2010-09-03 12:07:35

+0

該如何獲得價值多一些挖後的想法,我已經決定,這裏的問題是我的理解LINQ到SQL,而不是與表達式本身。我實體對象上的Enum屬性實際上並不是數據庫中的一列;我想這就是爲什麼它不能將它翻譯成where子句。我將採取不同的方法,但如果任何人有任何見解,請隨時分享。 – 2010-09-03 12:12:42

+0

你能提供MyClass的代碼嗎?您目前在帖子中的代碼是相當的樣板,從這裏沒有太多的說明... – code4life 2010-09-03 12:26:02

回答

0

嘗試

(int) enumMember 
+0

這不會編譯:「不能將類型'System.Linq.Expressions.MemberExpression'轉換爲'int'」 – 2010-09-03 11:31:08

+0

Heh,Sjoerd將是正確的...如果* enumMember *是一個實際的枚舉,而不是一個表達式樹的抽象。 – 2010-09-03 14:40:44

0

首先你必須修改枚舉一下我的朋友是這樣的:

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

後,你可以int和通過這種辦法,eunm之間的轉換:

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

這個答案是對這個問題的一個明顯的誤解--OP想知道如何使用表達式樹來處理枚舉類型。另外 - 枚舉在CLR中自然是'int'類型。這個問題對於帶有枚舉的C#表達式來說是一個很高的搜索結果,因此這個答案應該低於@philsoady的更合適的答案 – 2015-10-06 15:59:41

6

簡單地說,你不應該的,只要你告訴LINQ到SQL有關枚舉(而不是地圖ping它爲int並在C#中執行單獨的屬性來完成翻譯)。例如,以下工作正常:

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(); 

主要的一點是,我SomeProperty屬性在DBML到枚舉映射。簡單地使用枚舉類型(包括名稱空間)改寫類型名稱。

同樣,你不應該給它一個1,而應該是類型化的枚舉;例如:

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

(如果你知道是1

1

感謝馬克Gravell。 (Expression Guru!)請參閱正確的答案。 爲了適應這種情況,我對Expression Routine進行了更改。 正常屬性或枚舉。櫃面有人認爲這是很有幫助的

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); 
    }