Linq2Sql и lambda возвращают: «Метод« System.Object DynamicInvoke (System.Object []) »не имеет поддерживаемого перевода в SQL» - PullRequest
1 голос
/ 12 сентября 2011

Почему ...

Func<IQueryable<CampaignCodePaths>> table = () => CampaignCodePaths;

Func<CampaignCodePaths, int> propertySelector = e => e.Id;

int key = 1;

Func<CampaignCodePaths, bool> whereSelector = e => propertySelector(e).Equals(key);

table().Where(whereSelector).FirstOrDefault();

... работает, но ...

Func<IQueryable<CampaignCodePaths>> table = () => CampaignCodePaths;

Func<CampaignCodePaths, int> propertySelector = e => e.Id;

int key = 1;

table().Where(e => propertySelector(e).Equals(key)).FirstOrDefault();

... возвращает исключение:

Метод 'System.Object DynamicInvoke (System.Object [])' не имеет поддерживаемого перевода в SQL

UPDATE

уточнить:

CampaignCodePath Get(Func<IQueryable<CampaignCodePaths>> table, Func<CampaignCodePaths, int> selector, int key)
{
    return table().Where(/*How to I create this expression from selector and key? */).FirstOrDefault();
}

...

Get(() => CampaignCodePaths, e => e.Id, 1)

1 Ответ

5 голосов
/ 12 сентября 2011

Ваш первый фрагмент кода выполняет всю фильтрацию в .NET, потому что вы используете делегат вместо дерева выражений - даже не пытается преобразовать фильтр в SQL.Другими словами, дело не в том, что первый «работает», а во втором - нет, а в том, что первый не терпит неудачу, потому что на самом деле он не пытается сделать то, что вы ожидаете, тогда как второй делает.

Вторая форма вызывает Queryable.Where(IQueryable<T>, Expression<...>), тогда как первая вызывает Enumerable.Where(IEnumerable<T>, Func<...>).

Если вы измените свой код на:

Expression<Func<CampaignCodePaths, bool>> filter = e => e.Id.Equals(key);
table().Where(filter).FirstOrDefault();

, тогда все будет хорошо.

РЕДАКТИРОВАТЬ: Отвечая на ваши изменения, я думаю, что вы хотите что-то вроде:

CampaignCodePath Get(Func<IQueryable<CampaignCodePaths>> table,
                     Expression<Func<CampaignCodePaths, int> selector>,
                     int key)
{
    Expression equal = Expression.Equal(selector, Expression.Constant(key));
    var lambda = Expression.Lambda<Expression<Func<CampaignCodePaths, bool>>
        (equal, selector.Parameters);
    return table().Where(lambda).FirstOrDefault();
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...