从 QueryOver(或者 Fluent NHibernate 也许)中获取魔法字符串?

发布于 2024-09-12 11:12:01 字数 770 浏览 5 评论 0原文

使用 FluentNHibernate、新的 QueryOver API 和新的 Linq 提供程序的众多原因之一都是因为它们消除了“魔术字符串”,即表示属性或可以在编译时表示的其他内容的字符串。

遗憾的是,我正在使用 NHibernate 的空间扩展,但它尚未升级为支持 QueryOver 或 LINQ。因此,我被迫使用 QueryOver Lambda 表达式和字符串的组合来表示我想要查询的属性等。

我想做的是这样的——我想要一种方法来询问 Fluent NHibernate(或者可能是 NHibernate QueryOver API)神奇的字符串“应该是什么”。这是一个伪代码示例:

目前,我会写 --

var x = session.QueryOver<Shuttle>().Add(SpatialRestrictions.Intersects("abc", other_object));

我想写的是 --

var x = session.QueryOver<Shuttle>().Add(SpatialRestriction.Intersects(session.GetMagicString<Shuttle>(x => x.Abc), other_object));

有类似的东西可用吗?写起来会不会很困难?

编辑:我只是想指出,这不仅仅适用于空间——实际上任何尚未转换为 QueryOver 或 LINQ 的东西都可能受益。

One of the many reason to use FluentNHibernate, the new QueryOver API, and the new Linq provider are all because they eliminate "magic string," or strings representing properties or other things that could be represented at compile time.

Sadly, I am using the spatial extensions for NHibernate which haven't been upgraded to support QueryOver or LINQ yet. As a result, I'm forced to use a combination of QueryOver Lambda expressions and strings to represent properties, etc. that I want to query.

What I'd like to do is this -- I want a way to ask Fluent NHibernate (or perhaps the NHibernate QueryOver API) what the magic string "should be." Here's a pseudo-code example:

Currently, I'd write --

var x = session.QueryOver<Shuttle>().Add(SpatialRestrictions.Intersects("abc", other_object));

What I'd like to write is --

var x = session.QueryOver<Shuttle>().Add(SpatialRestriction.Intersects(session.GetMagicString<Shuttle>(x => x.Abc), other_object));

Is there anything like this available? Would it be difficult to write?

EDIT: I just wanted to note that this would apply for a lot more than spatial -- really anything that hasn't been converted to QueryOver or LINQ yet could be benefit.

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

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

发布评论

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

评论(2

皇甫轩 2024-09-19 11:12:01

更新

C# 6 中的 nameof 运算符为此提供了编译时支持。


有一个更简单的解决方案 - 表达式。

采取以下示例:

public static class ExpressionsExtractor
{
    public static string GetMemberName<TObj, TProp>(Expression<Func<TObj, TProp>> expression)
    {
        var memberExpression = expression.Body as MemberExpression;

        if (memberExpression == null)
            return null;

        return memberExpression.Member.Name;
    }
}

用法:

var propName = ExpressionsExtractor.GetMemberName<Person, int>(p => p.Id);

ExpressionsExtractor 只是一个建议,您可以将此方法包装在您想要的任何类中,也许作为扩展方法,或者最好是非静态类。

您的示例可能看起来有点像这样:

var abcPropertyName = ExpressionsExtractor.GetMemberName<Shuttle, IGeometry>(x => x.Abc);
var x = session.QueryOver<Shuttle>().Add(SpatialRestriction.Intersects(abcPropertyName, other_object));

update

The nameof operator in C# 6 provides compile time support for this.


There is a much simpler solution - Expressions.

Take the following example:

public static class ExpressionsExtractor
{
    public static string GetMemberName<TObj, TProp>(Expression<Func<TObj, TProp>> expression)
    {
        var memberExpression = expression.Body as MemberExpression;

        if (memberExpression == null)
            return null;

        return memberExpression.Member.Name;
    }
}

And the usage:

var propName = ExpressionsExtractor.GetMemberName<Person, int>(p => p.Id);

The ExpressionsExtractor is just a suggestion, you can wrap this method in whatever class you want, maybe as an extension method or preferably a none-static class.

Your example may look a little like this:

var abcPropertyName = ExpressionsExtractor.GetMemberName<Shuttle, IGeometry>(x => x.Abc);
var x = session.QueryOver<Shuttle>().Add(SpatialRestriction.Intersects(abcPropertyName, other_object));
玩套路吗 2024-09-19 11:12:01

假设我理解你的问题,你可能想要的是你拥有的每个实体的帮助器类,其中包含列名、属性名和其他有用的东西,特别是如果你想使用 ICriteria 搜索。 http://nhforge.org/wikis/general/open-source- project-ecosystem.aspx 有很多可能有帮助的项目。 NhGen (http://sourceforge.net/projects/nhgen/) 创建非常简单的帮助器类,可能会帮助您指出您可能想要的设计路径。

澄清编辑:在“我不明白”评论之后

简而言之,我认为目前还没有适合您的解决方案。 QueryOver 项目还没有达到您想要的程度。因此,同时作为一个可能的解决方案,删除魔术字符串构建一个辅助类,这样您的查询就变成

var x = session.QueryOver<Shuttle>().Add(SpatialRestrictions.Intersects(ShuttleHelper.Abc, other_object));

这样,您的魔术字符串位于其他一些属性后面(我只是选择 .Abc 来演示,但我确信您会拥有更好地了解您想要的内容)然后,如果“abc”更改(例如“xyz”),您可以将属性名称从 .Abc 更改为 .Xyz,然后您将出现构建错误,以显示您需要更新代码的位置(就像使用 lambda 表达式一样)或者只是将 .Abc 属性的值更改为“xyz” - 这实际上只有在您的属性具有一些有意义的名称(例如 .OtherObjectIntersectingColumn 等)而不是该属性名称本身时才有效。这样做的优点是不必更新代码来纠正构建错误。此时您的查询可能是

var x = session.QueryOver<Shuttle>().Add(SpatialRestrictions.Intersects(ShuttleHelper.OtherObjectIntersectingColumn, other_object));

我提到的开源项目生态系统页面,因为它可以为您提供一些有关其他人制作的帮助器类类型的指示,因此可以说您不必重新发明轮子。

Assuming I'm understanding your question what you might want is a helper class for each entity you have with things like column names, property names and other useful things, especially if you want to use ICriteria searches. http://nhforge.org/wikis/general/open-source-project-ecosystem.aspx has plenty of projects that might help. NhGen (http://sourceforge.net/projects/nhgen/) creates very simple helper classes which might help point you down a design path for what you might want.

Clarification Edit: following an "I don't understand" comment

In short, I don't beleive there is a solution for you just yet. The QueryOver project hasn't made it as far as you want it to. So as a possible solution in the mean time, to remove magic strings build a helper class, so your query becomes

var x = session.QueryOver<Shuttle>().Add(SpatialRestrictions.Intersects(ShuttleHelper.Abc, other_object));

That way your magic string is behind some other property ( I just chose .Abc to demonstrate but I'm sure you'll have a better idea of what you want ) then if "abc" changes ( say to "xyz" ) you either change the property name from .Abc to .Xyz and then you will have build errors to show you where you need to update your code ( much like you would with lambda expressions ) or just change the value of the .Abc property to "xyz" - which would really only work if your property had some meaningfull name ( such as .OtherObjectIntersectingColumn etc ) not that property name itself. That does have the advantage of not having to update code to correct the build errors. At that point your query could be

var x = session.QueryOver<Shuttle>().Add(SpatialRestrictions.Intersects(ShuttleHelper.OtherObjectIntersectingColumn, other_object));

I mentioned the open source project ecosystem page as it can give you some pointers on what types of helper classes other people have made so your not re-inventing the wheel so to speak.

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