扩展方法解决LinqToSql Contains超过2100行报错问题

时间:2022-06-05 12:37:25

1.扩展方法

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Linq.Expressions;
using System.Reflection; namespace Utils
{
//http://*.com/questions/567963/linq-expression-to-return-property-value/568771#568771
public static class ContainsExtensions
{
public static IEnumerable<T> InRange<T, TValue>(
this IQueryable<T> source,
Expression<Func<T, TValue>> selector,
int blockSize,
IEnumerable<TValue> values)
{
MethodInfo method = null;
foreach (MethodInfo tmp in typeof(Enumerable).GetMethods(
BindingFlags.Public | BindingFlags.Static))
{
if (tmp.Name == "Contains" && tmp.IsGenericMethodDefinition
&& tmp.GetParameters().Length == )
{
method = tmp.MakeGenericMethod(typeof(TValue));
break;
}
}
if (method == null) throw new InvalidOperationException(
"Unable to locate Contains");
foreach (TValue[] block in values.GetBlocks(blockSize))
{
var row = Expression.Parameter(typeof(T), "row");
var member = Expression.Invoke(selector, row);
var keys = Expression.Constant(block, typeof(TValue[]));
var predicate = Expression.Call(method, keys, member);
var lambda = Expression.Lambda<Func<T, bool>>(
predicate, row);
foreach (T record in source.Where(lambda))
{
yield return record;
}
}
}
public static IEnumerable<T[]> GetBlocks<T>(
this IEnumerable<T> source, int blockSize)
{
List<T> list = new List<T>(blockSize);
foreach (T item in source)
{
list.Add(item);
if (list.Count == blockSize)
{
yield return list.ToArray();
list.Clear();
}
}
if (list.Count > )
{
yield return list.ToArray();
}
}
}
}

2.调用

Using Utils;

void Test()

{

var ids=new int[] { 1,2,3 ... 9999 };

var list=datacontext.TestTable.InRange(ee => ee.Id, 2000, ids).ToList();

}

解决方案来自:http://*.com/questions/567963/linq-expression-to-return-property-value/568771#568771

From:http://www.cnblogs.com/xuejianxiyang/p/5491750.html