繁体   English   中英

基于内存中原语组合的查询的实体框架解决方法

[英]Entity Framework workaround for query based on combination of primitives in memory

我有T班:

class T {
   int Prop1Id;
   int Prop2Id;
}

在运行时,在内存中,我有:

var L1 = new List<T>();

L1包含以下T对象:

Prop1   Prop2
12       5
6        7
8        9
10       12 

无法执行以下操作:

attributes.Where(x=>L1.Any(y=>y.Prop1ID == x.Prop1ID && y.Prop2ID == x.Prop2ID))

attributes是EF类型(即:在数据库中)

这是行不通的,因为它无法创建T的常量值类型-它只需要基元和可枚举值。

除了带回所有属性以使它们以IEnumerable而不是IQueryable的形式存在于内存中之外,是否有人想出其他解决方法? 对我来说,这不是真正的选择:-(

假设您提供的是2个属性,它们都是整数类型。 因此,您可以尝试这种解决方法。 我们需要将您的列表转换为另一个字符串键列表,如下所示:

var stringKeys = L1.Select(e => e.Prop1 + "_" + e.Prop2);
//then use stringKeys normally
attributes.Where(x=> stringKeys.Contains(x.Prop1ID + "_" + x.Prop2ID));

如果不是这种情况(不限于整数属性),我们可能必须通过基于列表L1构建Where条件来以更复杂的方式进行操作:

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

上述方法可能效率较低。 它将执行L1.CountWHERE连接的(之前对数据库表UNION ALL )的所有结果。 但是我相信,如果在关键列上执行,性能仍然会很好。

最后一个解决方案是尝试使用“表达式树”(表示在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 (如应当既intfloat ,...)。 相同的条件适用于所有相应的属性。 否则,您需要修改代码以构建表达式树(此处的原因是Expression.Equal要求2个操作数表达式具有相同的数据类型)。 我没有使用表达式树测试最后的代码,但是这个想法很明确。

(内部)涉及Expression的最后一个选项是尝试使用LinqKit 我什至没有使用过该库,但是在许多情况下,它可以帮助您摆脱构建表达式树的麻烦。 因此,请尝试一下它是否可以帮助您运行原始查询而不会遇到提到的异常。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM