一個選項假設你提供了什麼,2個屬性是整數類型。所以,你可以試試這個變通,我們需要您的列表轉換成另一種字符串鍵列表如下:
var stringKeys = L1.Select(e => e.Prop1 + "_" + e.Prop2);
//then use stringKeys normally
attributes.Where(x=> stringKeys.Contains(x.Prop1ID + "_" + x.Prop2ID));
如果不是這種情況(不限於整數性能),我們可能有基於列表L1
打造的具備條件做更復雜的方式:
var result = attributes;
foreach(var e in L1){
var k1 = e.Prop1;
var k2 = e.Prop2;
var sub = attributes.Where(x => k1 == x.Prop1ID && k2 == x.Prop2ID);
result = result.Concat(sub);
}
//then access result instead of attributes
上述方法可能效率稍差。它將在連接(UNION ALL
)所有結果之前針對數據庫表執行L1.Count
次WHERE
。不過我相信,如果它在關鍵列上執行,性能仍然不錯。
最後溶液是嘗試使用表達式樹(表示Where
通過了謂詞):
//suppose your attributes is a set of Attribute
var p = Expression.Parameter(typeof(Attribute));
var p1 = Expression.Property(p, "Prop1ID");
var p2 = Expression.Property(p, "Prop2ID");
var initBool = Expression.Constant(false) as Expression;
//build the BodyExpression for the predicate
var body = L1.Aggregate(initBool, (c,e) => {
var ep1 = Expression.Constant(e.Prop1);
var ep2 = Expression.Constant(e.Prop2);
var and = Expression.And(Expression.Equal(ep1, p1), Expression.Equal(ep2,p2));
return Expression.Or(c, and);
});
attributes.Where(Expression.Lambda<Func<Attribute, bool>>(body, p));
注意的x.Prop1ID
類型應的L1.Prop1
每個元素的類型完全匹配(如既要int
或float
,...)。相同的條件適用於所有相應的屬性。否則,您需要修改代碼來構建表達式樹(這裏的原因是Expression.Equal
要求2個操作數表達式具有相同的數據類型)。我沒有使用表達式樹來測試最後一個代碼,但這個想法非常明確。
涉及Expression(內部)的最後一個選項是嘗試使用LinqKit
。我甚至沒有使用過這個庫,但它可以幫助您在很多情況下免費構建Expression樹。因此,如果它可以幫助您運行原始查詢而不會遇到您提到的異常,請嘗試一下。