Используя делегата, вы заставляете его использовать LINQ-to-Objects, поэтому ему не хватает памяти. Что вам нужно сделать, это построить Expression
вместо этого. В равной степени плохая практика - использовать атрибуты, поскольку это не единственная модель, поддерживаемая LINQ-to-SQL; предпочтительнее взглянуть на dataContext.Mapping.GetMetaType(entityType)
, чтобы получить первичный ключ.
Если у вас 4.0, должно работать следующее:
var entityType = typeof(User);
var metaType = dataContext.Mapping.GetMetaType(entityType);
var member = metaType.DataMembers.Single(m => m.IsPrimaryKey).Member;
var param = Expression.Parameter(entityType);
var body = Expression.Equal(Expression.MakeMemberAccess(param, member),
Expression.MakeMemberAccess(Expression.Constant(entity), member));
dynamic table = dataContext.GetTable(entityType);
object result = Cheeky(table, body, param);
с
static T Cheeky<T>(ITable<T> source, Expression body, ParameterExpression param)
where T : class
{
var predicate = Expression.Lambda<Func<T, bool>>(body, param);
return source.SingleOrDefault(predicate);
}