2011-07-06 25 views
3

我正在嘗試使用Linq2SQL加載實體的集合。問題是,我不知道實體是什麼,IList<object>。我嘗試使用反射來選擇它們,但是當我執行選擇時,出現內存不足錯誤,我推測因爲上下文無法解析我的表達式,並正在從數據庫中加載所有內容。Linq2SQL - 使用反射選擇項目

如果有人對此有任何建議,或者按照我的意願選擇其他方式,請告訴我。

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(); 
} 
+0

哦,我想避免動態LINQ如果可能的話 – jasper

+0

是集requiredEntities'的'單一類型? –

+0

不,多種類型 – jasper

回答

4

通過使用委託你迫使它使用LINQ到對象,這就是爲什麼它內存不足。你需要做的是建立一個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); 
} 
+0

完美,謝謝。從來不知道你可以將動態類型傳遞給這樣的通用方法。 – jasper

+0

@jasper實際上,這是我爲'dynamic'使用的少數幾個應用之一; p我喜歡我的代碼static-typed,但是'MakeGenericMethod' /'MakeGenericType'等等都是PITA - '動態的'來救援; p –