在我的代碼中的第(3)處,我定義了一個名爲query1的查詢,其中我定義了一個.Where lambda表達式。此查詢在某種程度上是動態的,但仍包含靜態元素,它始終引用類型員工及其(int)屬性ClientID。用表達式樹創建完全動態的where子句並在IQueryable上執行
現在我非常喜歡根據方法參數來指出類型及其屬性的動態,這些參數的示例如下面的點(1)所示。
我到目前爲止所做的嘗試是通過用(4),(5)&(6)中寫下的更精細的表達式樹替換它,使點(3)下定義的查詢的靜態部分完全動態化。 。但是,當我嘗試將所有內容添加到一起時,它說我打電話。帶有錯誤參數的地方。我不知道如何調用。用正確的參數爲了創建一個完全動態的選擇。
有人知道解決這個問題嗎?我花了一天的搜索時間,到目前爲止還沒有找到解決方案。
dsMain domainService = new dsMain();
//(1)i want to rewrite the following four variables to method-parameters
Type entityType = typeof(Employee);
String targetProperty = "ClientID";
Type entityProperty = typeof(Employee).GetProperty(targetProperty).PropertyType;
int idToDelete = 5;
//(2)create expression-function: idToDelete == entityType.targetProperty (in this case: Employee.ClientID)
ParameterExpression numParam = Expression.Parameter(entityProperty, targetProperty.Substring(0, 3));
ConstantExpression equalTarget = Expression.Constant(idToDelete, idToDelete.GetType());
BinaryExpression intEqualsID = Expression.Equal(numParam, equalTarget);
Expression<Func<int, bool>> lambda1 =
Expression.Lambda<Func<int, bool>>(
intEqualsID,
new ParameterExpression[] { numParam });
//(3)I want to create query1 fully dynamic, so defining Employee or an other type and its property at run time
WhereClause = lambda1.Compile();
IQueryable<Employee> employees = domainService.GetEmployees();
var query1 = employees.Where<Employee>(C => WhereClause.Invoke(C.ClientID)).Expression;
//(4)create the operand body {value(ASP.test_aspx).WhereClause.Invoke(E.ClientID)}
var operandbodyMethod = WhereClause.GetType().GetMethod("Invoke");
var operandbodyType = typeof(System.Boolean);
var operandbodyArgs1Expression = Expression.Parameter(entityType, entityType.Name.Substring(0, 1));
var operandbodyArgs1 = Expression.MakeMemberAccess(operandbodyArgs1Expression, entityType.GetMember(targetProperty)[0]);
var operandBodyObjectExp = Expression.Constant(this, this.GetType());
var operandbodyObject = Expression.MakeMemberAccess(operandBodyObjectExp, this.GetType().GetMember("WhereClause")[0]);
//(5)create the operand {E => value(ASP.test_aspx).WhereClause.Invoke(E.ClientID)}
var operandbody = Expression.Call(operandbodyObject, operandbodyMethod, operandbodyArgs1);
var operandParameter = Expression.Parameter(entityType, entityType.Name.Substring(0, 1));
var operandType = typeof(Func<,>).MakeGenericType(entityType, typeof(System.Boolean));
//(6)
var operand = Expression.Lambda(operandType, operandbody, new ParameterExpression[] { operandParameter });
var expressionType = typeof(Expression<>).MakeGenericType(operandType);
var completeWhereExpression = Expression.MakeUnary(ExpressionType.Quote, operand, expressionType);
//(7)the line below does not work
var query2 = employees.Where<Employee>(completeWhereExpression).Expression;
非常感謝您閱讀我的問題! 如果您有關於我的問題的問題,請讓他們:)
不管你用表達式樹創造什麼,你仍然需要有一個IQueryable來操作。在你的例子中,什麼是domainService?看起來像某種數據上下文,但不是LinqToSql的。你有一個方法,GetEmployees()就可以了,domainService是否提供了任何基於System.Type獲取IQueryable的機制,比如LinqToSql的呢? – 2010-08-09 22:30:54
domainService擴展了LinqToEntitiesDomainService(http://bit.ly/dr8Zkd),它是WCF RIA Services框架(http://bit.ly/aHusJT)的一部分。 domainService對於我的EDM中稱爲dbUbiHorecaEntities的每個實體都有特定的CRUD方法。它沒有特殊的機制來獲得基於System.Type的IQueryables,但是,它可能帶有反射:每個實體X在domainService中都有一個名爲getX()的get方法,返回一個IQueryable 。示例:IQueryable = domainService.GetType()。GetMethod(「Get」+ X.getType()。GetName())。Invoke(domainService,null)。這對你有幫助嗎? –
2010-08-09 22:57:55