Linq2Sql 和 lambda 返回“方法‘System.Object DynamicInvoke(System.Object[])’”不支持 SQL 转换”

发布于 2024-12-04 09:03:44 字数 1103 浏览 0 评论 0原文

为什么...

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 的转换

更新

澄清:

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)

Why does...

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();

...work but...

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

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

int key = 1;

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

...returns exception:

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

?

UPDATE

To clarify:

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)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

池木 2024-12-11 09:03:46

您的第一段代码是在 .NET 中执行所有过滤,因为您使用的是委托而不是表达式树 - 它甚至没有尝试将过滤器转换为 SQL。换句话说,并不是第一个“有效”而第二个不行——而是第一个不会失败,因为它并没有真正尝试做你所期望的事情,而第二个却成功了。

第二种形式是调用 Queryable.Where(IQueryable, Expression<...>),而第一种形式是调用 Enumerable.Where(IEnumerable, 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();
}

Your first piece of code is performing all the filtering in .NET because you're using a delegate instead of an expression tree - it's not even trying to convert the filter into SQL. In other words, it's not that the first "works" and the second doesn't - it's that the first doesn't fail because it doesn't really try to do what you're expecting, whereas the second does.

The second form is calling Queryable.Where(IQueryable<T>, Expression<...>) whereas the first is calling Enumerable.Where(IEnumerable<T>, Func<...>).

If you change your code to:

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

then it should be fine.

EDIT: Responding to your edit, I think you want something like:

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();
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文