C# Linq2SQL-使用反射选择项

C# Linq2SQL-使用反射选择项,c#,.net,linq-to-sql,reflection,C#,.net,Linq To Sql,Reflection,我正在尝试使用Linq2SQL加载一组实体。问题是,我不知道实体是什么,IList。我曾尝试使用反射来选择它们,但我在执行选择时出现内存不足错误,我认为这是因为上下文无法解析我的表达式,并且正在从数据库加载所有内容 如果有人对此有任何建议,或者有其他方法来做我想做的事情,请让我知道 foreach (object entity in requiredEntities) { Type entityType = entity.GetType(); IQueryable<object

我正在尝试使用Linq2SQL加载一组实体。问题是,我不知道实体是什么,
IList
。我曾尝试使用反射来选择它们,但我在执行选择时出现内存不足错误,我认为这是因为上下文无法解析我的表达式,并且正在从数据库加载所有内容

如果有人对此有任何建议,或者有其他方法来做我想做的事情,请让我知道

foreach (object entity in requiredEntities)
{
   Type entityType = entity.GetType();
   IQueryable<object> entityTable = (IQueryable<object>)dataContext.GetTable(entityType);               

   // grab the objects primary key field
   var pkeyField = entityType.GetProperties().SingleOrDefault(p =>
                   p.GetCustomAttributes(typeof(System.Data.Linq.Mapping.ColumnAttribute),true)
                   .Cast<System.Data.Linq.Mapping.ColumnAttribute>() 
                   .Any(attrib => attrib.IsPrimaryKey));

   object pkeyValue = pkeyField.GetValue(entity,null);

   Func<object,bool> primaryKeySelector = o => pkeyField.GetValue(o,null) == pkeyValue;

   // crash here, out of memory exception
   object result = entityTable.Where(primaryKeySelector).SingleOrDefault();
}
foreach(需求实体中的对象实体)
{
类型entityType=entity.GetType();
IQueryable entityTable=(IQueryable)dataContext.GetTable(entityType);
//抓取对象主键字段
var pkeyField=entityType.GetProperties().SingleOrDefault(p=>
p、 GetCustomAttributes(typeof(System.Data.Linq.Mapping.ColumnAttribute),true)
.Cast()
.Any(attrib=>attrib.IsPrimaryKey));
对象pkeyValue=pkeyField.GetValue(实体,空);
Func primaryKeySelector=o=>pkeyField.GetValue(o,null)==pkeyValue;
//在此崩溃,内存不足异常
对象结果=entityTable.Where(primaryKeySelector.SingleOrDefault();
}

通过使用委托,您强制它使用LINQ to对象,这就是它内存不足的原因。您需要做的是构建一个
表达式
。同样,使用属性也是不好的做法,因为它不是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 checkey(ITable源代码、表达式体、参数Expression param)
T:在哪里上课
{
var谓词=Expression.Lambda(body,param);
返回source.SingleOrDefault(谓词);
}

噢,如果可能的话,我想避免使用动态linq。这是单一类型的
requiredEntities
集合?太好了,谢谢。从来都不知道可以将动态类型传递给这样的泛型方法。@jasper实际上,这是我对
dynamic
;p我喜欢静态类型的代码,但是
MakeGenericMethod
/
MakeGenericType
等都是一个PITA-
动态类型的
;P
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);
}