我開始使用NHibernate 3 linq提供程序,它很棒。到目前爲止,我已經用Criteria使用了NHibernate空間。NHibernate空間使用NHibernate 3 linq提供程序空間
我如何使用NHibernate空間使用LINQ?
謝謝你,羅恩
我開始使用NHibernate 3 linq提供程序,它很棒。到目前爲止,我已經用Criteria使用了NHibernate空間。NHibernate空間使用NHibernate 3 linq提供程序空間
我如何使用NHibernate空間使用LINQ?
謝謝你,羅恩
我不知道這是否是可能的開箱即用。或者在linq提供商中使用NH掛鉤來執行它,或者像我在這裏發佈的那樣執行它https://stackoverflow.com/a/9585622/671619
自你最初發布問題以來已經過去了一段時間,但是,因爲你沒有標記爲回答,所以讓我給你看一個我寫過關於這個主題的博客文章,展示了在HQL和LINQ中使用NH Spatial的幾個查詢示例。
你可以檢查一下here
晚的答案,但肯定的,你可以在LINQ查詢使用NHibernate.Spatial。您必須使用NHibernate.Spatial分支之一(例如:@psousa這裏的:https://github.com/pmcxs/Nhibernate.Spatial或@suryapratap這裏的https://github.com/suryapratap/Nhibernate.Spatial)。
支持的操作範圍可以通過查看源代碼在NHibernate.Spatial.Linq.Functions.SpatialLinqToHqlGeneratorsRegistry 源文件中找到。例如這個代碼在這裏:
public class AnalysisDistanceGenerator : SpatialMethodGenerator<IGeometry, double>
{
public AnalysisDistanceGenerator() : base(g => g.Distance(null)) { }
}
這意味着你應該能夠做到這樣的查詢:
dbSession.Query<Entity>().Where(x => x.Location.Distance(point) < 50).FirstOrDefault();
有一個錯誤(或實際上,它是在NHibernate的設計監督)導致像上面的查詢需要一個Point實例失敗,錯誤:
ArgumentException: 24204: The spatial reference identifier (SRID) is not valid.
這是因爲NHibernate的嘗試找到一個NHibernate的ITYPE實例使用coverting「點」數據典型值e(參數)轉換爲SQL並最終找不到任何內容,因此它使用默認的SerializableType,它不尊重您在點實例本身上設置的SRID參數。
監督是NHibernate本身不允許指定「實體持久化」(作爲從/到SQL的類型轉換器)超出它自帶的默認值。對於加載或保存實體,它使用爲從類映射(hbm/xml,fluent或通過代碼映射)編譯的實體定義的元數據,這樣可以工作,但對於非映射Point實例,它只是處理它們錯誤。
在NHibernate中花費了很多小時的調試之後,解決方案只是簡單地讓NHibernate處理Point和IPoint實例,就好像它們是內置類型一樣,方法是爲它註冊一個IType(然後可以爲它定義SRID,子類型),它工作正常。
不幸的是,這個方法使用反射來訪問標記爲private的NHibernate.Type.TypeFactory.RegisterType方法。我無法找到任何公共API來實現此方法。
只需在創建NHibernate SessionFactory時(在應用程序啓動時)調用此方法一次。顯然,它假設您將對所有未明確設置其SRID的點參數使用默認SRID 4326。您可以傳遞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 }
});
}
我不能得到這個工作。我在創建會話工廠時調用了該方法,但隨後出現了不同的運行時錯誤。 – nfplee 2014-06-12 08:51:33