3 回答

TA貢獻(xiàn)1851條經(jīng)驗 獲得超4個贊
我是很新,Linq和EF
您很不走運,因為“簡單的事情”在LINQ to Objects中相對容易,但是在LINQ to Entities中卻相當(dāng)困難(幾乎不可能)。
為了以某種方式解決它,您需要手動構(gòu)建LINQ to Entitiescompatible Expression。
首先,您需要一些幫助程序來構(gòu)建表達(dá)謂詞。PredicateBuilder是一個流行的選擇,但它不會產(chǎn)生EF兼容表情和要求LinqKit,并AsExpandable在倉庫里。因此,我使用以下類似的輔助方法,但會產(chǎn)生最終的兼容表達(dá)式:
public static class PredicateUtils
{
sealed class Predicate<T>
{
public static readonly Expression<Func<T, bool>> True = item => true;
public static readonly Expression<Func<T, bool>> False = item => false;
}
public static Expression<Func<T, bool>> Null<T>() { return null; }
public static Expression<Func<T, bool>> True<T>() { return Predicate<T>.True; }
public static Expression<Func<T, bool>> False<T>() { return Predicate<T>.False; }
public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> left, Expression<Func<T, bool>> right)
{
if (Equals(left, right)) return left;
if (left == null || Equals(left, True<T>())) return right;
if (right == null || Equals(right, True<T>())) return left;
if (Equals(left, False<T>()) || Equals(right, False<T>())) return False<T>();
var body = Expression.AndAlso(left.Body, right.Body.Replace(right.Parameters[0], left.Parameters[0]));
return Expression.Lambda<Func<T, bool>>(body, left.Parameters);
}
public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> left, Expression<Func<T, bool>> right)
{
if (Equals(left, right)) return left;
if (left == null || Equals(left, False<T>())) return right;
if (right == null || Equals(right, False<T>())) return left;
if (Equals(left, True<T>()) || Equals(right, True<T>())) return True<T>();
var body = Expression.OrElse(left.Body, right.Body.Replace(right.Parameters[0], left.Parameters[0]));
return Expression.Lambda<Func<T, bool>>(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);
}
}
}
其次,在控制器中為這樣的單個條件定義一個輔助方法
static Expression<Func<Person, bool>> AbilityFilter(int index, int value)
{
return p => p.AllAbilities.OrderBy(a => a.Id).Skip(index).Take(1).Any(a => a.Value > value);
}
最后,構(gòu)建過濾器并將其傳遞給GetAll方法:
var filter = PredicateUtils.Null<Person>();
for (int i = 0; i < AbilitiesInput.Count; i++)
filter = filter.And(AbilityFilter(i, AbilitiesInput[i]));
GetAll(filter);
使用的技術(shù)絕對不是新手,但我認(rèn)為沒有簡單的方法可以解決該特定問題。

TA貢獻(xiàn)1801條經(jīng)驗 獲得超8個贊
不知道我是否正確,但是下面的代碼可能有助于獲得正確的解決方案。使用(x,i)將枚舉整個集合并獲得一個索引,以便您可以比較兩個集合。
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<TextBox> AbilitiesInput = null;
public Form1()
{
InitializeComponent();
AbilitiesInput = new List<TextBox>() { textBox1, textBox2, textBox3, textBox4 };
Person person = new Person();
List<Ability> results = person.AllAbilities.Where((x, i) => x.Value > int.Parse(AbilitiesInput[i].Text)).ToList();
}
}
public class Person
{
public int Id { get; set; }
public List<Ability> AllAbilities { get; set; }
public Person()
{
AllAbilities = new List<Ability>();
}
}
public class Ability
{
public int Id { get; set;}
public int PersonId { get; set; }
public int Value { get; set; }
}
}

TA貢獻(xiàn)1801條經(jīng)驗 獲得超16個贊
非常感謝您的答復(fù),但是為了在查詢的where子句中使用它,我需要一個布爾值而不是List<Ability> results
。我如何將其更改為布爾值?我嘗試用替換Where
,All
但All
似乎無法處理(x, i)
。
- 3 回答
- 0 關(guān)注
- 474 瀏覽
添加回答
舉報