Ich erhalte die folgenden FehlerKombinieren mehrerer Ausdrücke Bäume
Der Parameter ‚p‘ nicht in der angegebenen LINQ to Entities Abfrageausdruck gebunden war.
Ich verstehe das Problem (die gleiche Instanz von ParameterExpression
sollte mit allen Ausdrücken im Baum verwendet werden) und haben versucht, Lösungen zu verwenden, habe ich online, aber ohne Glück gefunden.
Dies ist meine Methode
private void SeedEntity<TEntity>(DatabaseContext context, ref TEntity entity, params Expression<Func<TEntity, object>>[] identifierExpressions) where TEntity : class
{
Expression<Func<TEntity, bool>> allExpresions = null;
var parameters = identifierExpressions.SelectMany(x => x.Parameters).GroupBy(x => x.Name).Select(p => p.First()).ToList();
foreach (Expression<Func<TEntity, object>> identifierExpression in identifierExpressions)
{
Func<TEntity, object> vv = identifierExpression.Compile();
object constant = vv(entity);
ConstantExpression constExp = Expression.Constant(constant, typeof(object));
BinaryExpression equalExpression1 = Expression.Equal(identifierExpression.Body, constExp);
Expression<Func<TEntity, bool>> equalExpression2 = Expression.Lambda<Func<TEntity, bool>>(equalExpression1, parameters);
if (allExpresions == null)
{
allExpresions = equalExpression2;
}
else
{
BinaryExpression bin = Expression.And(allExpresions.Body, equalExpression2.Body);
allExpresions = Expression.Lambda<Func<TEntity, bool>>(bin, parameters);
}
}
TEntity existingEntity = null;
if (allExpresions != null)
{
existingEntity = context.Set<TEntity>().FirstOrDefault(allExpresions);
}
if (existingEntity == null)
{
context.Set<TEntity>().Add(entity);
}
else
{
entity = existingEntity;
}
}
Es erzeugt einen Ausdruck für die Suche eines Unternehmens auf eine Reihe von Eigenschaften basieren.
Es funktioniert gut für einen einzelnen Ausdruck, der Fehler tritt nur bei der Übergabe in mehreren.
wie folgt aufgerufen:
SeedEntity(context, ref e, p=> p.Name);//Works
SeedEntity(context, ref e, p=> p.Name, p=> p.Age);//Fails
Es erzeugt etwas Ähnliches mir folgendes ausführen:
context.Set<TEntity>().FirstOrDefault(p=>p.Name == e.Name && p.Age == e.Age);
Ersetzen e.Name & & E.age mit einem können Sie ConstantExpression
siehe in der Methode oben greife ich alle einzigartigen params und speichern sie in parameters
an der zu p, dann verwenden Sie die gleiche Variable durch. Dies ist der Start, aber dann muss ich die Instanzen des Parameters in jedem der Expression<Func<TEntity, bool>>
übergeben als das params
Array ersetzen, das ist, wo ich versage.
Ich habe versucht, die Ausdrücke aufzuzählen und die .Update()
Methode Gang in den params
Ich habe auch versucht, eine Lösung verwenden, die ExpressionVisitor
public class ExpressionSubstitute : ExpressionVisitor
{
public readonly Expression from, to;
public ExpressionSubstitute(Expression from, Expression to)
{
this.from = from;
this.to = to;
}
public override Expression Visit(Expression node)
{
if (node == from) return to;
return base.Visit(node);
}
}
public static class ExpressionSubstituteExtentions
{
public static Expression<Func<TEntity, TReturnType>> RewireLambdaExpression<TEntity, TReturnType>(Expression<Func<TEntity, TReturnType>> expression, ParameterExpression newLambdaParameter)
{
var newExp = new ExpressionSubstitute(expression.Parameters.Single(), newLambdaParameter).Visit(expression);
return (Expression<Func<TEntity, TReturnType>>)newExp;
}
}
Nur ein kurzer Gedanke, haben Sie versucht, einen anderen Buchstaben für den zweiten Parameter zu verwenden? (dh p => p.Name, f => f.Age) –
Danke für die Eingabe, dies würde nie funktionieren, da Sie nur einen Parameter haben, aber Ihre Weitergabe in zwei. Es wird Falsche Anzahl der Parameter für Lambda –
liefern Anstatt die Abfragen zu kombinieren, warum sie nicht nacheinander anwenden? 'results =/* Vollständiger Satz * /; foreach (Ausdruck) {results = results.Where (Ausdruck)} '? Da EF "IQueryable" verwendet, verschiebt das Framework die Ausführung, bis es benötigt wird, und kombiniert dann alle Prädikate zu einer einzigen Abfrage für SQL. – Basic