2013-02-05 25 views
2

我有一個簡單的linq-to-sql語句,它將string[]中的值與表中的值匹配,並返回匹配的表值。重構linq-to-sql方法返回匹配值

_table的類型是System.Data.Linq.Table<TEntity>

public IEnumerable<ZipCode> match(IEnumerable<string> values) { 
    HashSet<string> valueSet = new HashSet<string>(values); 
    return _table.Where(x => valueSet.Contains(x.zipcode); 
} 

的我如何重構,這樣我可以通過現場使用到Contains()

我的失敗嘗試:

public IEnumerable<ZipCode> match<T>(IEnumerable<T> values, 
     Expression<Func<ZipCode, T>> field) { 
    HashSet<T> valueSet = new HashSet<T>(values); 
    return _table.Where(x => valueSet.Contains(field(x))); 
} 

這會產生錯誤:

Method 'System.Object DynamicInvoke(System.Object[])' has no supported translation to SQL.

我的想法是,我可以用表達式樹給了Contains()的領域,但困惑於如何或是否這甚至是使用表達式的正確方法。完全可能有更好的解決方案。

+0

這被標記爲'linq-to-sql' - 你的意思是'linq'嗎? –

+0

我會詳細說明我的問題... _table是'System.Data.Linq.Table' – bflemi3

回答

0

代替Expression<Func<ZipCode, T>> field使用:

public IEnumerable<ZipCode> match<T>(IEnumerable<T> values, Func<ZipCode, T> field) 
{ 
    HashSet<T> valueSet = new HashSet<T>(values); 
    return _table.Where(x => valueSet.Contains(field(x))); 
} 
+1

這給出了錯誤「方法'System.Object DynamicInvoke(System.Object [])'沒有支持轉換到SQL。 「 – bflemi3

2

我能夠使用以下(在.NET 4.5,但我相信它會在早期版本的工作)

static IEnumerable<TTable> Match<TTable, TField>(IQueryable<TTable> table, IEnumerable<TField> values, Expression<Func<TTable, TField>> fieldSelector) 
{ 
    var valuesConstant = Expression.Constant(values.Distinct()); 

    var callContains = Expression.Call(typeof(Enumerable), "Contains", new[] { typeof(TField) }, new Expression[] { valuesConstant, fieldSelector.Body }); 

    var whereExpression = Expression.Lambda<Func<TTable, bool>>(callContains, (fieldSelector.Body as MemberExpression).Expression as ParameterExpression); 

    return table.Where(whereExpression); 
} 

你應該能夠刪除我使用的表格參數並使用你有的成員變量。