Establecer un enlace entre dos listas en linq a entidades donde cláusula

Soy bastante nuevo para Linq y EF y estoy atascado con respecto a cómo podría simplemente vincular dos listas en Linq a Entidades.

Estoy usando Database First y tengo dos tablas:

Person , con columnas Id
y
Ability , con columnas Id , PersonId y Value

Por lo tanto, la clase Person tiene una ICollection , llamada AllAbilities .

En el ViewModel de alguna Vista, obtengo una lista de int, representando textboxes valores ingresados ​​por el usuario para Ability.Value , llamado AbilitiesInput . Mi necesidad es simple, en el controlador tengo que llamar a una consulta que haría lo siguiente:

 GetAll(person => for(i = 0; i  AbilitiesInput[i] } ) 

Donde el método GetAll se ve así en mi repo genérico:

 public virtual async Task<List> GetAll( Expression<Func> wherePredicate = null { ... } 

Para reanudarlo, solo necesito un booleano que pueda verificar si cada AllAbilities[i] es superior a AbilitiesInput[i] , pero nada de lo que intenté ha funcionado.
Traté de cambiar AbilitiesInput a List o List pero recibí un error que decía que No mapping exists , traté de usar un Select para crear un nuevo objeto, también intenté usar IndexOf o FindIndex para obtener el índice sin foreach. .

Si alguien pudiera explicarme cómo puedo lograr esta simple cosa, sería así, tan feliz.
Muchas gracias.

Soy bastante nuevo para Linq y EF

No tiene suerte, porque “esta cosa simple” es relativamente fácil en LINQ to Objects, pero bastante difícil (casi imposible) en LINQ to Entities.

Para resolverlo de alguna manera, debe comstackr manualmente LINQ to Entities Expression compatible.

Primero, necesitarás algunos ayudantes para construir predicados de expresiones. PredicateBuilder es una opción popular, pero no produce expresiones compatibles con EF y requiere LinqKit y AsExpandable dentro del repository. Así que uso los siguientes ayudantes que son similares, pero producen expresiones compatibles finales:

 public static class PredicateUtils { sealed class Predicate { public static readonly Expression> True = item => true; public static readonly Expression> False = item => false; } public static Expression> Null() { return null; } public static Expression> True() { return Predicate.True; } public static Expression> False() { return Predicate.False; } public static Expression> And(this Expression> left, Expression> right) { if (Equals(left, right)) return left; if (left == null || Equals(left, True())) return right; if (right == null || Equals(right, True())) return left; if (Equals(left, False()) || Equals(right, False())) return False(); var body = Expression.AndAlso(left.Body, right.Body.Replace(right.Parameters[0], left.Parameters[0])); return Expression.Lambda>(body, left.Parameters); } public static Expression> Or(this Expression> left, Expression> right) { if (Equals(left, right)) return left; if (left == null || Equals(left, False())) return right; if (right == null || Equals(right, False())) return left; if (Equals(left, True()) || Equals(right, True())) return True(); var body = Expression.OrElse(left.Body, right.Body.Replace(right.Parameters[0], left.Parameters[0])); return Expression.Lambda>(body, left.Parameters); } static Expression Replace(this Expression expression, Expression source, Expression target) { return new ExpressionReplacer { Source = source, Target = target }.Visit(expression); } class ExpressionReplacer : ExpressionVisitor { public Expression Source; public Expression Target; public override Expression Visit(Expression node) { return node == Source ? Target : base.Visit(node); } } } 

Segundo, defina un método de ayuda en su controlador para un solo criterio como este

 static Expression> AbilityFilter(int index, int value) { return p => p.AllAbilities.OrderBy(a => a.Id).Skip(index).Take(1).Any(a => a.Value > value); } 

Finalmente, construya el filtro y páselo al método GetAll :

 var filter = PredicateUtils.Null(); for (int i = 0; i < AbilitiesInput.Count; i++) filter = filter.And(AbilityFilter(i, AbilitiesInput[i])); GetAll(filter); 

Las técnicas utilizadas definitivamente no son para principiantes, pero no veo una manera simple de resolver ese problema en particular.

No estoy seguro si lo hice bien, pero el siguiente código puede ayudar a obtener la solución correcta. El uso de (x, i) enumerará a través de la colección y obtendrá un índice para que pueda comparar las dos colecciones.

 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; namespace WindowsFormsApplication1 { public partial class Form1 : Form { List AbilitiesInput = null; public Form1() { InitializeComponent(); AbilitiesInput = new List() { textBox1, textBox2, textBox3, textBox4 }; Person person = new Person(); List results = person.AllAbilities.Where((x, i) => x.Value > int.Parse(AbilitiesInput[i].Text)).ToList(); } } public class Person { public int Id { get; set; } public List AllAbilities { get; set; } public Person() { AllAbilities = new List(); } } public class Ability { public int Id { get; set;} public int PersonId { get; set; } public int Value { get; set; } } }