- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我的 LINQ 查询之一有问题。查询如下所示:
Dim elements = (From filterSum In dataContext.GetTable(Of TblFilterSum)
Join filterProdInSum In dataContext.GetTable(Of TblFilterProdsInSum)
On filterSum.SumID Equals filterProdInSum.SumID
Join filterProd In dataContext.GetTable(Of TblFilterProd)
On filterProdInSum.ProdID Equals filterProd.ProdID
Join filterElementInProd In dataContext.GetTable(Of TblFilterElementsInProd)
On filterProd.ProdID Equals filterElementInProd.ProdID
Join filterElement In dataContext.GetTable(Of TblFilterElement)
On filterElementInProd.ElementID Equals filterElement.ElementID
Where sumIDs.Contains(filterSum.SumID)).Select(Function(r) New With {.SumID = r.filterSum.SumID, .ProdID = r.filterProd.ProdID, .filterElement = r.filterElement, .IsNotSum = r.filterSum.IsNot, .IsNotProd = r.filterProd.IsNot}).ToList
此查询从表定义的 5 维问题空间加载记录:
tblFilterSum
tblFilterProdsInSum
tblFilterProd
tblFilterElementsInProd
tblFilterElement
我在 Where
子句中使用的过滤器是 tblFilterSum.SumID
位于名为 sumIDs 的
。 Linq 查询在逻辑上是无可挑剔的,并且正好有我需要的结果。然而,执行它需要很长时间,平均执行时间为 20 秒。这是 LINQ 查询生成的 SQL:List(Of Integer)
中
-- Region Parameters
DECLARE @p0 Int = 12168
DECLARE @p1 Int = 12157
DECLARE @p2 Int = 11948
DECLARE @p3 Int = 11951
DECLARE @p4 Int = 11952
DECLARE @p5 Int = 11950
DECLARE @p6 Int = 11961
DECLARE @p7 Int = 12153
DECLARE @p8 Int = 12154
DECLARE @p9 Int = 12149
DECLARE @p10 Int = 12158
DECLARE @p11 Int = 11954
DECLARE @p12 Int = 11955
DECLARE @p13 Int = 11956
DECLARE @p14 Int = 11957
DECLARE @p15 Int = 11958
DECLARE @p16 Int = 11959
DECLARE @p17 Int = 12159
DECLARE @p18 Int = 12164
DECLARE @p19 Int = 12150
DECLARE @p20 Int = 12151
DECLARE @p21 Int = 12152
DECLARE @p22 Int = 12156
DECLARE @p23 Int = 12161
DECLARE @p24 Int = 12167
DECLARE @p25 Int = 11962
DECLARE @p26 Int = 12155
DECLARE @p27 Int = 12183
DECLARE @p28 Int = 12182
DECLARE @p29 Int = 12165
DECLARE @p30 Int = 12166
DECLARE @p31 Int = 11953
DECLARE @p32 Int = 12163
DECLARE @p33 Int = 12181
DECLARE @p34 Int = 12180
DECLARE @p35 Int = 12160
DECLARE @p36 Int = 12162
-- EndRegion
SELECT [t0].[SumID], [t2].[ProdID], [t4].[ElementID], [t4].[Field], [t4].[Operator], [t4].[Result], [t4].[IsCustom], [t4].[IsNot], [t4].[DisplayOrder], [t4].[FilteredColumnID], [t4].[ColumnMappingID], [t4].[ResultPointerToAssetPath], [t4].[ResultCustomColumnMappingID], [t0].[IsNot] AS [IsNotSum], [t2].[IsNot] AS [IsNotProd]
FROM [dbo].[tblFilterSum] AS [t0]
INNER JOIN [dbo].[tblFilterProdsInSum] AS [t1] ON [t0].[SumID] = [t1].[SumID]
INNER JOIN [dbo].[tblFilterProd] AS [t2] ON [t1].[ProdID] = [t2].[ProdID]
INNER JOIN [dbo].[tblFilterElementsInProd] AS [t3] ON [t2].[ProdID] = [t3].[ProdID]
INNER JOIN [dbo].[tblFilterElement] AS [t4] ON [t3].[ElementID] = [t4].[ElementID]
WHERE [t0].[SumID] IN (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10, @p11, @p12, @p13, @p14, @p15, @p16, @p17, @p18, @p19, @p20, @p21, @p22, @p23, @p24, @p25, @p26, @p27, @p28, @p29, @p30, @p31, @p32, @p33, @p34, @p35, @p36)
-- Context: SqlProvider(Sql2008) Model: MappedMetaModel Build: 4.6.1055.0
GO
如果我直接运行它,它会立即运行,因此问题是 .NET Framework 4.0 下的 LINQ 每次执行时都会编译查询,并且没有任何缓存。虽然有可能缓存结果:System.Data.Linq.CompiledQuery.Compile是一种有用的方法,可以用它来编译 LINQ 查询。它返回的 Func
可以使用不同的参数一次又一次地重用,围绕 .NET Framework 4.0 中使用的始终编译策略工作。这个想法是为每个可能的查询创建一个唯一的签名,并使用共享字典,我们可以将每种查询编译一次,存储到缓存中,然后将其与其他属性一起重用。这听起来不错,但看看可能的用法:
Public Shared Function Compile(Of TArg0 As DataContext, TResult)(query As Expression(Of Func(Of TArg0, TResult))) As Func(Of TArg0, TResult)
Public Shared Function Compile(Of TArg0 As DataContext, TArg1, TResult)(query As Expression(Of Func(Of TArg0, TArg1, TResult))) As Func(Of TArg0, TArg1, TResult)
Public Shared Function Compile(Of TArg0 As DataContext, TArg1, TArg2, TResult)(query As Expression(Of Func(Of TArg0, TArg1, TArg2, TResult))) As Func(Of TArg0, TArg1, TArg2, TResult)
Public Shared Function Compile(Of TArg0 As DataContext, TArg1, TArg2, TArg3, TResult)(query As Expression(Of Func(Of TArg0, TArg1, TArg2, TArg3, TResult))) As Func(Of TArg0, TArg1, TArg2, TArg3, TResult)
Public Shared Function Compile(Of TArg0 As DataContext, TArg1, TArg2, TArg3, TArg4, TResult)(query As Expression(Of Func(Of TArg0, TArg1, TArg2, TArg3, TArg4, TResult))) As Func(Of TArg0, TArg1, TArg2, TArg3, TArg4, TResult)
Public Shared Function Compile(Of TArg0 As DataContext, TArg1, TArg2, TArg3, TArg4, TArg5, TResult)(query As Expression(Of Func(Of TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TResult))) As Func(Of TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TResult)
Public Shared Function Compile(Of TArg0 As DataContext, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TResult)(query As Expression(Of Func(Of TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TResult))) As Func(Of TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TResult)
Public Shared Function Compile(Of TArg0 As DataContext, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TResult)(query As Expression(Of Func(Of TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TResult))) As Func(Of TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TResult)
Public Shared Function Compile(Of TArg0 As DataContext, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TResult)(query As Expression(Of Func(Of TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TResult))) As Func(Of TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TResult)
Public Shared Function Compile(Of TArg0 As DataContext, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TResult)(query As Expression(Of Func(Of TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TResult))) As Func(Of TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TResult)
Public Shared Function Compile(Of TArg0 As DataContext, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TResult)(query As Expression(Of Func(Of TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TResult))) As Func(Of TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TResult)
Public Shared Function Compile(Of TArg0 As DataContext, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TResult)(query As Expression(Of Func(Of TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TResult))) As Func(Of TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TResult)
Public Shared Function Compile(Of TArg0 As DataContext, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TResult)(query As Expression(Of Func(Of TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TResult))) As Func(Of TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TResult)
Public Shared Function Compile(Of TArg0 As DataContext, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TResult)(query As Expression(Of Func(Of TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TResult))) As Func(Of TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TResult)
Public Shared Function Compile(Of TArg0 As DataContext, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TResult)(query As Expression(Of Func(Of TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TResult))) As Func(Of TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TResult)
Public Shared Function Compile(Of TArg0 As DataContext, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TArg15, TResult)(query As Expression(Of Func(Of TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TArg15, TResult))) As Func(Of TArg0, TArg1, TArg2, TArg3, TArg4, TArg5, TArg6, TArg7, TArg8, TArg9, TArg10, TArg11, TArg12, TArg13, TArg14, TArg15, TResult)
我很快意识到我有两个问题。这一次,Compile
方法具有不同可能参数值的重载,以及它返回的 Func
的相同数量的参数。这是一个不太严重的问题,因为我可以为我拥有的每个元素数量缓存一个编译查询。它会浪费一些内存,但不会浪费那么多。如果它太多了,我会用 Redis 存储它,但这是一个不同的问题。真正的问题是参数的数量不能超过 16 个,而我的 List
可以很容易地包含更多元素。对于这个问题,解决方案是将 sumIDs
转换为 String
,每个数字之间有一个分隔符,字符串将以该分隔符开始和结束,如下所示:
,5,2,7,34,764,346,1,
并检查此 String
是否包含转换为 String
的给定 tblFilterSum.SumID
,如下所示:
"," & tblFilterSum.SumID & ","
但是虽然这可行,但它不能使用索引并且它会比较字符串,这会非常慢。由于我遇到了这些问题并且任务很紧迫,我用 SQL 实现了它,但想知道我是否可以编译一个 LINQ 查询并确保任意多的参数可以作为 List
传递,例如。因此我的问题:
如何使用 List 作为参数编译 LINQ 查询?
编辑:
如果我知道如何联系 LINQ 的创建者,那么我相信我自己就能找到答案。我在 google 上搜索了 LINQ,但不幸的是我没有找到联系信息。
最佳答案
使用 Contains()
的查询 cannot be automatically cached .所以解决方案必须是避免 Contains
方法。为此,我们必须通过 Linq 表达式 API 创建等效表达式 (f => f.SumID == x || f.SumId == y ...
)。
以下解决方案使用 ExpressionCombiner来自 netfx。这是C#,转换成VB应该很简单。
public static IQueryable<T> WherePropertyIn<T, TProp>(this IQueryable<T> src, Expression<Func<T, TProp>> property, IEnumerable<TProp> values) {
var valuesList = values.ToList();
// If no values passed, then nothing matches
if (!valuesList.Any()) {
return src.Where(_ => false);
}
// This builds the 'f => f.Prop == x || f.Prop == y ...' expression
Expression<Func<T, bool>> expr = valuesList
.Select(val => property.EqualTo(val)) // Here we have a list of 'f => f.Prop == x' style expressions
.Aggregate(ExpressionCombiner.Or); // And combine them with ||
return src.Where(expr);
}
// Creates an expression 'f => f.Prop == val' out of expression 'f => f.Prop' and value 'val'
private static Expression<Func<T, bool>> EqualTo<T, TProperty>(this Expression<Func<T, TProperty>> leftHand, TProperty val) {
// If we don't wrap in property access, LINQ to Entities uses the value directly instead of via a sql parameter, thus breaking caching.
Expression rightHand = Expression.Constant(val, typeof(TProperty)).WrapInPropertyAccess();
Expression comparison = Expression.Equal(leftHand.Body, rightHand);
return Expression.Lambda<Func<T, bool>>(comparison, leftHand.Parameters);
}
/// <summary>
/// Returns an expression around the ConstantExpression, enabling LINQ to Entities to generate parameterized queries
/// </summary>
/// <param name="constant"></param>
/// <returns></returns>
private static UnaryExpression WrapInPropertyAccess(this ConstantExpression constant) {
Tuple<object> container = new Tuple<object>(constant.Value);
Expression containerExpression = Expression.Constant(container, typeof(Tuple<object>));
MemberExpression propAccess = Expression.Property(containerExpression, "Item1");
UnaryExpression result = Expression.Convert(propAccess, constant.Type); // Cast back the object to the value type
return result;
}
您的查询现在可以使用此代码:
Dim filterSumSubQuery = dataContext.GetTable(Of TblFilterSum).WherePropertyIn(Function(t) r.SumID, sumIDs)
' Subquery now contains only the TbFilterSum tuples that have the right SumIDs
关于sql-server - 如何使用 List 参数编译 LINQ 查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40046956/
我想使用 R 预定义这样的列表 DATA<-list( list(list(),list(),list()), list(list(),list(),list()), list(list(),l
如何将一个列表添加到另一个列表,返回一个列表的列表? foo :: [a] -> [a] -> [[a]] 例如,我想要的结果是: foo [1,2] [3,4] 将是 [[1,2], [3,4]]。
我还没有在这里找到类似问题的解决方案,所以我会寻求你的帮助。 有 2 个列表,其中之一是列表列表: categories = ['APPLE', 'ORANGE', 'BANANA'] test_re
这个问题不同于Converting list of lists / nested lists to list of lists without nesting (这会产生一组非常具体的响应,但无法解决
原始列表转换为 List正好。为什么原始列表的列表不能转换为 List 的列表? { // works List raw = null; List wild = raw; } {
在下面的代码中,get()被调用并将其结果分配给类型为 List> 的变量. get()返回 List>并在类型参数为 T 的实例上调用设置为 ? ,所以它应该适合。 import java.util
原始列表转换为 List正好。为什么原始列表的列表不能转换为 List 的列表? { // works List raw = null; List wild = raw; } {
在insufficiently-polymorphic 作者说: def foo[A](fst: List[A], snd: List[A]): List[A] There are fewer way
我有下面的代码有效。 class ListManipulate(val list: List, val blockCount: Int) { val result: MutableList>
关闭。这个问题需要多问focused 。目前不接受答案。 想要改进此问题吗?更新问题,使其仅关注一个问题 editing this post . 已关闭 5 年前。 Improve this ques
在 scala (2.9) 中转换列表列表的最佳方法是什么? 我有一个 list : List[List[A]] 我想转换成 List[A] 如何递归地实现这一点?或者还有其他更好的办法吗? 最佳答案
我编写了这个函数来确定给定元素是否存储在元组列表的列表中,但目前它只搜索第一个列表。我将如何搜索其余列表? fun findItem (name : command, ((x,y)::firstlis
我创建了一个类名 objectA,它有 4 个变量:约会时间;字符串文本;变量 1,变量 2 我需要创建一个 ObjectA() 列表。然后首先按时间对它们进行分组,其次按 var1,然后按 var2
我有一套说法 char={'J','A'} 和列表的列表 content = [[1,'J', 2], [2, 'K', 3], [2, 'A', 3], [3,'A', 9], [5, 'J', 9
我有以下列表 List >>> titles = new ArrayList >>> ();我想访问它的元素,但我不知道该怎么做.. 该列表有 1 个元素,它又包含 3 个元素,这 3 个元素中的
转换 List[List[Long]] 的最佳方法是什么?到 List[List[Int]]在斯卡拉? 例如,给定以下类型列表 List[List[Long]] val l: List[List[Lo
我有一个来自 Filereader (String) 的 List-List,如何将其转换为 List-List (Double):我必须返回一个包含 line-Array 的第一个 Values 的
我收集了List> 。我需要将其转换为List> 。这是我尝试过的, List> dataOne = GetDataOne(); var dataTwo = dataOne.Select(x => x
这个问题在这里已经有了答案: Cannot convert from List to List> (3 个答案) 关闭 7 年前。 我没有得到这段代码以任何方式编译: List a = new Ar
这个问题在这里已经有了答案: Cannot convert from List to List> (3 个答案) 关闭 7 年前。 我没有得到这段代码以任何方式编译: List a = new Ar
我是一名优秀的程序员,十分优秀!