我遇到了 ODAC(Oracle 数据访问组件)、实体框架 4.3.1 和表达式树的问题。我们有一个在实体框架中映射的遗留数据库(不是吗?)。该表有数百万条记录和一百多列(悲伤的脸)。
以下是对索引列的示例查询:
int myId = 2;
var matchingRecord = context.MyLargeTable.Where(v=>v.Id == myId).ToList(); //Super slow (5+ minutes, sometimes Out of Memory exception)
int myId = 2;
Expression<Func<bool>> myLambda = v => v.Id == myId; //Shouldn't this work now?
var matchingRecord = context.MyLargeTable.Where(myLambda).ToList(); //Still super slow (5+ minutes, sometimes Out of Memory exception)
var elementName = Expression.Parameter(typeof(LargeTable), "v");
var propertyName = Expression.Parameter(elementName, "Id");
var constantValue = Expression.Constant(myId);
var comparisonMethod = Expression.Call(
propertyName,
typeof(int).GetMethod("Equals", new[] { typeof(int) }),
constantValue
)
var finalTree = Expression.Lambda<Func<LargeTable, bool>>(comparisonMethod, elementName);
var matchingRecord = context.MyLargeTable.Where(finalTree).ToList(); //Super fast
我读过这样的文章,解释了 Func<> 和 Expression> 之间的区别以及 Expression> 实际上如何传递到数据库进行查询,这就是它更快的原因。
http://www.fascinatedwithsoftware.com/blog/post/2011/12/02/Falling-in-Love-with-LINQ-Part-7-Expressions-and-Funcs.aspx - 一切都很好,但如果在匆忙,只需阅读标题为“意外后果”的部分即可了解主要内容
为什么要使用 Expression<Func<T>> 而不是 Func<T>?- 如果没有相应的 SO 问题,任何链接都是不完整的
我的问题是:人们真的坐在那里使用 Expression.* 类构建表达式树吗?除了简单比较之外的任何查询都变得非常复杂,几乎无法阅读。将 Expression> 传递给数据库时我缺少什么?对于这个手动构建的表达式树解决方案,我该打谁的脸?甲骨文?英孚?我错过了什么?