Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将NHibernate 3 linq提供程序与NHibernate spatial一起使用_Linq_Nhibernate_Spatial - Fatal编程技术网

将NHibernate 3 linq提供程序与NHibernate spatial一起使用

将NHibernate 3 linq提供程序与NHibernate spatial一起使用,linq,nhibernate,spatial,Linq,Nhibernate,Spatial,我开始与NHibernate 3 linq提供商合作,这很好。 到目前为止,我一直使用NHibernate spatial标准 如何将linq与NHibernate结合使用 谢谢, 罗恩我不知道这是否是现成的。要么使用linq提供程序中的NH钩子来实现它,要么像我在这里发布的那样执行它自从您最初发布问题以来,已经过了一段时间,但由于您没有将其标记为已回答,所以让我向您展示我在这个主题上写的一篇博客文章,其中展示了在HQL和linq中使用NH Spatial的几个查询示例 您可以检查它,但可以在L

我开始与NHibernate 3 linq提供商合作,这很好。 到目前为止,我一直使用NHibernate spatial标准

如何将linq与NHibernate结合使用

谢谢,
罗恩

我不知道这是否是现成的。要么使用linq提供程序中的NH钩子来实现它,要么像我在这里发布的那样执行它

自从您最初发布问题以来,已经过了一段时间,但由于您没有将其标记为已回答,所以让我向您展示我在这个主题上写的一篇博客文章,其中展示了在HQL和linq中使用NH Spatial的几个查询示例


您可以检查它,但可以在LINQ查询中使用NHibernate.Spatial。您必须使用一个NHibernate.Spatial分叉(例如:这里是@psousa的分叉:或者这里是@suryapratap的分叉)

通过查看NHibernate.Spatial.Linq.Functions.spatiallinqtohqlngeneratorregistry中的源代码,可以猜测支持的操作范围 源文件。例如,下面的代码:

public class AnalysisDistanceGenerator : SpatialMethodGenerator<IGeometry, double>
{
    public AnalysisDistanceGenerator() : base(g => g.Distance(null)) { }
}
之所以会出现这种情况,是因为NHibernate试图找到一个NHibernate IType实例,用于将“点”数据类型(参数)转换为SQL,但最终没有找到任何内容,因此它使用默认的SerializableType,它不尊重您在点实例本身上设置的SRID参数

疏忽之处在于,NHibernate本身不允许在其自身注册的默认持久器之外指定“实体持久器”(充当从/到SQL的类型转换器)。对于加载或保存实体,它使用为从类映射(hbm/xml、fluent或代码映射)编译的实体定义的元数据,这样可以工作,但对于未映射的点实例,它只是错误地处理它们

在NHibernate中花费数小时进行调试后,解决方案就是通过为NHibernate注册IType(然后您可以为其定义SRID、子类型),使NHibernate将Point和IPoint实例当作内置类型来处理,并且工作正常

不幸的是,此方法使用反射来访问标记为private的NHibernate.Type.TypeFactory.RegisterType方法。我找不到任何公共API来实现此方法

只需在创建NHibernate SessionFactory(应用程序内启动)期间调用此方法一次。显然,它假设您将对所有未显式设置SRID的点参数使用默认SRID4326。如果需要,可以为参数字典传递null,而不是指定默认SRID和子类型

它很难看,但效果很好:

    static void RegisterGeometryTypeForIPointUsingReflection()
    {
        var methods =
            typeof(TypeFactory).GetMethods(BindingFlags.NonPublic | BindingFlags.Static);

        var requiredOverload = methods.Where(
            x =>
            {
                if (x.Name != "RegisterType") return false;

                var args = x.GetParameters();
                if (args.Length != 2) return false;

                return args[0].ParameterType == typeof(IType)
                       && args[1].ParameterType == typeof(IEnumerable<string>);
            })
            .FirstOrDefault();

        if (requiredOverload == null)
        {
            throw new NotSupportedException(
                "Could not find TypeFactory.RegisterType method overload in NHibernate. Please report this issue.");
        }

        requiredOverload.Invoke(
            null,
            new object[]
            {
                new CustomType(
                    typeof(GeometryType),
                    new Dictionary<string, string>
                    {
                        { "srid", "4326" },
                        { "subtype", "POINT" }
                    }),
                new[]
                { typeof(IPoint).AssemblyQualifiedName, typeof(Point).AssemblyQualifiedName }
            });
    }
静态无效注册表GeometryTypeForIpIntusingReflection()
{
var方法=
typeof(TypeFactory).GetMethods(BindingFlags.NonPublic | BindingFlags.Static);
var requiredOverload=方法。其中(
x=>
{
如果(x.Name!=“RegisterType”)返回false;
var args=x.GetParameters();
如果(args.Length!=2)返回false;
返回参数[0]。参数类型==typeof(IType)
&&args[1]。参数类型==typeof(IEnumerable);
})
.FirstOrDefault();
if(requiredOverload==null)
{
抛出新的NotSupportedException(
“在NHibernate中找不到TypeFactory.RegisterType方法重载。请报告此问题。”);
}
requiredOverload.Invoke(
无效的
新对象[]
{
新客户类型(
类型(几何类型),
新词典
{
{“srid”,“4326”},
{“子类型”,“点”}
}),
新[]
{typeof(IPoint).AssemblyQualifiedName,typeof(Point).AssemblyQualifiedName}
});
}

我无法让它工作。我在创建会话工厂时调用了该方法,但随后出现了一个不同的运行时错误。
ArgumentException: 24204: The spatial reference identifier (SRID) is not valid.
    static void RegisterGeometryTypeForIPointUsingReflection()
    {
        var methods =
            typeof(TypeFactory).GetMethods(BindingFlags.NonPublic | BindingFlags.Static);

        var requiredOverload = methods.Where(
            x =>
            {
                if (x.Name != "RegisterType") return false;

                var args = x.GetParameters();
                if (args.Length != 2) return false;

                return args[0].ParameterType == typeof(IType)
                       && args[1].ParameterType == typeof(IEnumerable<string>);
            })
            .FirstOrDefault();

        if (requiredOverload == null)
        {
            throw new NotSupportedException(
                "Could not find TypeFactory.RegisterType method overload in NHibernate. Please report this issue.");
        }

        requiredOverload.Invoke(
            null,
            new object[]
            {
                new CustomType(
                    typeof(GeometryType),
                    new Dictionary<string, string>
                    {
                        { "srid", "4326" },
                        { "subtype", "POINT" }
                    }),
                new[]
                { typeof(IPoint).AssemblyQualifiedName, typeof(Point).AssemblyQualifiedName }
            });
    }