Erstellen Sie eine geschachtelte Lambda-Ausdrucksbaumstruktur für eine Entity Framework-Beziehung "Viele zu viele"?

.net entity-framework expression-trees linq many-to-many

Frage

Ich versuche, einen Entity Framework 4 Many to Many Beziehungsfilter zu erstellen, dies ist für ein dynamisches Datenprojekt. Ich weiß, dass ich zur Laufzeit einen Ausdrucksbaum erstellen muss, und ich bin vertraut damit, das für so etwas wie einen einfachen Ausdruck zu tun:

private MethodCallExpression BuiltMethodCall(IQueryable _query, Type _ObjType, string _ColumnToSearch, string _SearchValue)
{
ConstantExpression value = Expression.Constant(_SearchValue);
ParameterExpression _parameter = Expression.Parameter(_ObjType, "value");
MemberExpression _property = Expression.Property(_parameter, _ColumnToSearch);
BinaryExpression comparison = Expression.Equal(_property, value);
LambdaExpression lambda = Expression.Lambda(comparison, _parameter);

//Ex: Customers.Select(c => c).Where(value => (value.City == "Seattle"))
MethodCallExpression _where = Expression.Call(typeof(Queryable), "Where", new Type[] { _query.ElementType }, new Expression[] {
    _query.Expression,
    Expression.Quote(lambda)
});
return _where;

}

Der Einfachheit halber wird in diesen Beispielen die Northwind-Datenbank verwendet, in der sich viele (viele) Kunden (Kunden <- CustomerCustomerDemo -> CustomerDemographics) befinden. Worauf ich Probleme habe, ist das Erstellen des Ausdrucksbaums, wenn ein verschachteltes Lambda wie im folgenden Ausdruck vorhanden ist, in dem ich alle Kunden abrufe, die eine bestimmte Kundendemographie haben.

string custDemogID = "3";

//Get customers who have a particular demog
dynamic cust = context.Customers.Where(c => c.CustomerDemographics.Any(cd => cd.CustomerTypeID == custDemogID));

Wie erstelle ich den Ausdrucksbaum mit einem "Where" -Aufruf, der das verschachtelte Lambda für "Any" enthält? Jede Hilfe wird geschätzt, auch wenn es Pseudo-Code ist, wie es gemacht wird. Da ist nicht viel davon, ich bin verzweifelt, bitte hilf!

Akzeptierte Antwort

Hier ist die Lösung, die ich mir ausgedacht habe, meine größte Hilfe kam aus dem Aufruf einer Methode aus einem Ausdruck. Die größte Sache, die ich überwinden musste, war eine generische "Any" -Methode zu erstellen. Der Rest verkettet nur die Anrufe.

private MethodCallExpression BuiltMethodCall(IQueryable _query, string CustTypeID, Type _ParentObjType, Type _ChildObjType, string strChildObj, string strChildCol)
{

//This function will build a dynamic linq expression tree representing the ling calls of:
//Customers.Where(c => c.CustomerDemographics.Any(cd => cd.CustomerTypeID = custTypeID))

ConstantExpression value = Expression.Constant(CustTypeID);

//Build the outer part of the Where clause
ParameterExpression parameterOuter = Expression.Parameter(_ParentObjType, "c");
MemberExpression propertyOuter = Expression.Property(parameterOuter, strChildObj);

//Build the comparison inside of the Any clause
ParameterExpression parameterInner = Expression.Parameter(_ChildObjType, "cd");
MemberExpression propertyInner = Expression.Property(parameterInner, strChildCol);

BinaryExpression comparison = Expression.Equal(propertyInner, value);
LambdaExpression lambdaInner = Expression.Lambda(comparison, parameterInner);

//Create Generic Any Method
Func<MethodInfo, bool> methodLambda = m => m.Name == "Any" && m.GetParameters().Length == 2;
MethodInfo method = typeof(Enumerable).GetMethods().Where(methodLambda).Single().MakeGenericMethod(_ChildObjType);

//Create the Any Expression Tree and convert it to a Lambda
MethodCallExpression callAny = Expression.Call(method, propertyOuter, lambdaInner);
LambdaExpression lambdaAny = Expression.Lambda(callAny, parameterOuter);

//Build the final Where Call
MethodCallExpression whereCall = Expression.Call(typeof(Queryable), "Where", new Type[] { _query.ElementType }, new Expression[] {
    _query.Expression,
    Expression.Quote(lambdaAny)
});

return whereCall;

}



Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum