将Where() 转换为sql

发布于 2024-08-23 00:40:51 字数 1452 浏览 3 评论 0原文

我看到了DamienG的文章(http ://damieng.com/blog/2009/06/24/client-side-properties-and-any-remote-linq-provider)了解如何将客户端属性映射到 SQL。 我读完了这篇文章,我看到了它的巨大潜力。将客户端属性映射到 SQL 绝对是一个很棒的主意。

但我想用它来做一些比连接字符串更复杂的事情。 Atm,我们正在尝试向我们的 Business 对象引入多语言性,我希望我们可以完整保留所有现有的 linq2sql 查询,而只需更改多语言属性的代码,这样它们实际上会返回 CurrentUICulture 中的给定属性。

第一个想法是将这些字段更改为 XML,然后尝试 Object.Property.Elements().Where(...),但它卡在了 Elements() 上,因为它无法将其转换为 sql。我在某处读到 XML 字段实际上被视为字符串,并且仅在应用程序服务器上它们才成为 XElements,因此这样过滤无论如何都会在应用程序服务器上,而不是数据库上。公平地说,它不会像这样工作。让我们尝试别的东西... 所以第二个想法是创建一个 PolyGlots 表(名称取自 http: //weblogic.sys-con.com/node/102698?page=0,1),一个 PolyGlotTranslations 表和一个 Culture 表,其中将从每个国际化属性引用 PolyGlots。举例来说,我想说的是:

private static readonly CompiledExpression<Announcement, string> nameExpression
    = DefaultTranslationOf<Announcement>
        .Property(e => e.Name)
        .Is(e=> e.NamePolyGlot.PolyGlotTranslations
          .Where(t=> t.Culture.Code == Thread.CurrentThread.CurrentUICulture.Name)
          .Single().Value
        );

现在不幸的是,我收到一个错误,即Where()函数无法转换为sql,这有点令人失望,因为我确信它会通过。 我猜它失败了,因为 IEntitySet 基本上是一个 IEnumerable,而不是 IQueryable,我对吗?

是否有另一种方法可以使用compileExpressions类来实现这个目标? 任何帮助表示赞赏。

I saw DamienG's article (http://damieng.com/blog/2009/06/24/client-side-properties-and-any-remote-linq-provider) in how to map client properties to sql.
i ran throgh this article, and i saw great potential in it. Definitely mapping client properties to SQL is an awesome idea.

But i wanted to use this for something a bit more complicated then just concatenating strings. Atm we are trying to introduce multilinguality to our Business objects, and i hoped we could leave all the existing linq2sql queries intact, and just change the code of the multilingual properties, so they would actually return the given property in the CurrentUICulture.

The first idea was to change these fields to XMLs, and then try the Object.Property.Elements().Where(...), but it got stuck on the Elements(), as it couldnt translate it to sql. I read somewhere that XML fields are actually regarded as strings, and only on the app server they become XElements, so this way the filtering would be on the app server anyways, not the DB. Fair point, it wont work like this. Lets try something else...
SO the second idea was to create a PolyGlots table (name taken from http://weblogic.sys-con.com/node/102698?page=0,1), a PolyGlotTranslations table and a Culture table, where the PolyGlots would be referenced from each internationalized property. This way i wanted to say for example:

private static readonly CompiledExpression<Announcement, string> nameExpression
    = DefaultTranslationOf<Announcement>
        .Property(e => e.Name)
        .Is(e=> e.NamePolyGlot.PolyGlotTranslations
          .Where(t=> t.Culture.Code == Thread.CurrentThread.CurrentUICulture.Name)
          .Single().Value
        );

now unfortunately here i get an error that the Where() function cannot be translated to sql, what is a bit disappointing, as i was sure it will go through.
I guess it is failing, cause the IEntitySet is basically an IEnumerable, not IQueryable, am i right?

Is there another way to use the compiledExpressions class to achieve this goal?
Any help appreciated.

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

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

发布评论

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

评论(2

无人问我粥可暖 2024-08-30 00:40:51

首先,我不会尝试将 XML 扩展纳入 SQL。它们是为不同的野兽设计的,这是有原因的。

有了正确的数据库策略,您应该能够摆脱一组 linq 查询。 (您可能需要调整它们以适应新模型。)例如,如果您的描述字段因语言而异,则创建一个视图,该视图将根据所选语言返回正确的描述。现在将 linq 查询指向视图而不是表。

附加信息:
每个包含多语言字段的项目只有一个视图。每个多语言字段都有自己的表,使用语言表键和原始对象的键作为复合键。该视图将所有表组合回一个位置以进行查询。现在假设我们有一个产品视图。如果我通过 ProductId = 1 查询该视图,我实际上会看到与语言一样多的产品副本。

现在,您的 Linq 查询将始终包含一个按语言限制的参数。请务必在查询中使用外部联接,这样如果某种语言的描述丢失,您仍然可以找回它。 (或者不使用它来故意将项目限制为所选语言的设置。

您可以创建存储过程来打开更新视图的能力,使其像表格一样工作。(或者您可以使用大多数 ARM 框架来执行此操作)通过连接那里的存储过程。)

First, I would not try to wrestle the XML extensions into SQL. They were designed for different beasts for a reason.

With the right database strategy, you should be able to get away with a single set of linq queries. (You may need to adjust them to fit the new model.) For instance if you have a description field that is different depending on the language, than create a view that will return the correct description based on the language of choice. Now point your linq query to the view instead of the tables.

Additional Information:
You only have one view per item that will contain multilingual fields. Each multilingual field has its own table using a language table key and the original object's key as a compound key. The view combines all the tables back into a single place to query. Now say we have a product view. If I query that view by ProductId = 1 I will actually see as many copies of the product as there are languages.

Now your Linq queries will always contain a parameter to limit by language. Just be sure to use an outer join in your query so that if the description in a language is missing you will still get it back. (Or not use it to intentionally limit the items to those setup for the language of choice.

You can create stored procs to open up the ability to update the view making it act like a table. (Or you can do this with most ARM frameworks by wiring up the stored procs there.)

¢好甜 2024-08-30 00:40:51

嗯,实际的问题是,Where 使用的不是来自 System.Linq 命名空间的,而是另一个,并且 ef 的表达式访问者无法翻译它。

Well, the actual problem was, that the Where used was not the one from the System.Linq namespace, but another one, and that was not translatable by the expression visitor of ef.

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