Linq2SQL -使用反射选择项目
本文关键字:选择 项目 反射 Linq2SQL | 更新日期: 2023-09-27 18:01:33
我正在尝试使用Linq2SQL加载实体集合。问题是,我不知道实体是什么,IList<object>
。我试图使用反射来选择它们,但是当我做选择时,我得到了内存不足的错误,我认为是因为上下文无法解析我的表达式,并且正在从DB加载一切。
如果有人对此有任何建议,或者有其他方法可以做我想做的事,请告诉我。
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();
}
通过使用委托,您强制它使用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);
}