Linq2Sql和lambda返回"方法"System.Object DynamicInvoke(System.Object [])'没有支持的SQL转换"

Nie*_*sma 1 c# linq-to-sql

为什么...

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();
Run Code Online (Sandbox Code Playgroud)

......工作但......

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

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

int key = 1;

table().Where(e => propertySelector(e).Equals(key)).FirstOrDefault();
Run Code Online (Sandbox Code Playgroud)

...返回异常:

方法'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)
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 5

您的第一段代码是在.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();
Run Code Online (Sandbox Code Playgroud)

那应该没问题.

编辑:响应您的编辑,我想你想要的东西:

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();
}
Run Code Online (Sandbox Code Playgroud)