在 Select 语句中调用表达式 - LINQ to Entity Framework

发布于 2024-09-11 07:44:14 字数 1219 浏览 7 评论 0原文

我正在尝试使用我在尝试执行 select 子句时创建的现有表达式构建类,但我不确定如何将表达式附加到 Select 的表达式树,我尝试执行以下操作:

var catalogs = matchingCatalogs.Select(c => new
                {
                    c.CatalogID,
                    Name = EntitiesExpressionHelper.MakeTranslationExpression<Catalog>("Name", ApplicationContext.Instance.CurrentLanguageID).Compile().Invoke(c),
                    CategoryName = EntitiesExpressionHelper.MakeTranslationExpression<Category>("Name", ApplicationContext.Instance.CurrentLanguageID).Compile().Invoke(c.Category),
                    c.CategoryID,
                    c.StartDateUTC,
                    c.EndDateUTC
                });

但我显然收到错误,指出实体框架无法将 Invoke 映射到 SQL 方法。有办法解决这个问题吗?

仅供参考,EntitiesExpressionHelper.MakeTranslationExpression(string name, int languageID) 相当于:

x => x.Translations.Count(t => t.LanguageID == languageID) == 0 ? x.Translations.Count() > 0 ? x.Translations.FirstOrDefault().Name : "" : x.Translations.FirstOrDefault(t => t.LanguageID == languageID).Name

编辑:我意识到我需要使用 ExpressionVisitor 来完成此操作,但我不确定如何使用 ExpressionVisitor 来更改MemberInitExpression,所以如果有人知道如何完成此操作,请告诉我。

I'm trying to use an already existing Expression building class that I made when trying to do a select clause, but I'm not sure how to attach the expression to the expression tree for the Select, I tried doing the following:

var catalogs = matchingCatalogs.Select(c => new
                {
                    c.CatalogID,
                    Name = EntitiesExpressionHelper.MakeTranslationExpression<Catalog>("Name", ApplicationContext.Instance.CurrentLanguageID).Compile().Invoke(c),
                    CategoryName = EntitiesExpressionHelper.MakeTranslationExpression<Category>("Name", ApplicationContext.Instance.CurrentLanguageID).Compile().Invoke(c.Category),
                    c.CategoryID,
                    c.StartDateUTC,
                    c.EndDateUTC
                });

But I obviously get the error stating that the Entity Framework can't map Invoke to a SQL method. Is there a way to work around this?

FYI, EntitiesExpressionHelper.MakeTranslationExpression<T>(string name, int languageID) is equivalent to:

x => x.Translations.Count(t => t.LanguageID == languageID) == 0 ? x.Translations.Count() > 0 ? x.Translations.FirstOrDefault().Name : "" : x.Translations.FirstOrDefault(t => t.LanguageID == languageID).Name

EDIT: I realize that I need to use an ExpressionVisitor to accomplish this, but I'm not sure how to use an ExpressionVisitor to alter the MemberInitExpression, so if anyone knows how to accomplish this, let me know.

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

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

发布评论

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

评论(1

锦爱 2024-09-18 07:44:14

您需要捕获 vars 中的表达式。您将无法使用匿名类型。总的想法是,这是可行的:

Expression<Func<Foo, Bar>> exp = GenExpression();
var q = matchingCatalogs.Select(exp);

但这不会:

var q = matchingCatalogs.Select(GenExpression());

第一个愉快地将 GenExpression结果传递给 L2E。第二个尝试将 GenExpression 本身而不是结果传递给 L2E。

因此,您需要引用与表达式相同类型的 var。这些不能隐式类型化,因此您的结果类型需要一个真实类型。

You need to capture the expressions in vars. You won't be able to use anonymous types. The general idea is that this works:

Expression<Func<Foo, Bar>> exp = GenExpression();
var q = matchingCatalogs.Select(exp);

But this will not:

var q = matchingCatalogs.Select(GenExpression());

The first happily passes the result of GenExpression to L2E. The second tries to pass GenExpression itself to L2E, rather than the result.

So you need a reference to a var of the same type as the expression. Those can't be implicitly typed, so you'll need a real type for your result type.

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