I've assigned the Jira issue to myself and will take a look to determine what the fix should be. If it's easy, thne I'll just drop it in, if I need help then I may enlist you David :)
On Fri, Aug 20, 2010 at 2:10 PM, David Pfeffer <[email protected]> wrote: > Yes, I was trying to make it general so that it would be useful for someone > else working on something different in the future... here's a concrete > example: > > There's a method called Distance, as you mentioned, which is: > public static double Distance(IGeometry that) { ... } > > It isn't an extension method but rather is an implementation method. > > So I go and make a class SpatialGenerator which implements > IHqlGeneratorForMethod and whose SupportedMethods property returns a list > containing that Distance method, gotten by > > ReflectionHelper.GetMethodDefinition<IGeometry>(x => x.Distance(null)) > > Then BuildHql returns using the MethodCall as you mentioned earlier... > > return treeBuilder.MethodCall("NHSP.Distance", > visitor.Visit(targetObject).AsExpression(), > visitor.Visit(arguments[0]).AsExpression()); > > The generator is hooked in by a child of DefaultLinqToHqlGeneratorsRegistry > that calls RegisterGenerator, and in my test's config I do > > myconfig.SetProperty(Environment.LinqToHqlGeneratorsRegistry, > > > typeof > (Extensions.SpatialGeneratorsRegistry). > > AssemblyQualifiedName) > > I attempt to run a query next... > > var test = s.Query<TestModel.PositionRecord>().Where(x => > x.Position.Distance(mylocation) <= 500).ToList(); > > If this were to work properly, I should receive back all PositionRecord > entities where the distance from that entity to mylocation is within 500 > meters. But of course I get the "No persister for: > GeoAPI.Geometries.IGeometry" exception because there's no way for it to know > to use the IUserType I have for IGeometry. I haven't seen any place to plug > this in as of yet. > > > On Fri, Aug 20, 2010 at 8:00 AM, Fabio Maulo <[email protected]> wrote: > >> Can you transform ExampleMethod and ExampleType in something concrete.... >> for example Distance and IGeography or something like that ? >> >> Have you the set of extensions methods for NHSP ? >> >> >> On Fri, Aug 20, 2010 at 7:51 AM, David Pfeffer <[email protected]>wrote: >> >>> That is roughly what I have. However, when you call visitor.Visit on the >>> argument in question there is the exception because of it not knowing which >>> IType to map to. >>> >>> The ExampleMethod and ExampleType I refer to was from my example in an >>> earlier email... >>> >>> >>> public static bool ExampleMethod(this int x, ExampleType y) { ... } >>> >>> Even if I map this method using a generator with buildHql method, I still >>> don't have a way to specify the IType for *ExampleType* from the above >>> example. >>> >>> >>> On Thu, Aug 19, 2010 at 11:14 PM, Fabio Maulo <[email protected]>wrote: >>> >>>> I don't know what "ExampleMethod" and "ExampleType" are but if >>>> "ExampleType" have some meaning for persistence you can translate it to >>>> IType as we are doing for any parameter. >>>> >>>> David, I know that perhaps it doesn't look easy to implement but this is >>>> OSS. >>>> >>>> btw... backing to the title of this thread... >>>> NHSP has the registration of some HQLFunction you can map the name of >>>> the extension with the name of the HQLFunction (using exactly the same name >>>> or using a dictionary) and then you can use >>>> >>>> treeBuilder.MethodCall(theHqlFunctionName, >>>> visitor.Visit(expression).AsExpression()); >>>> >>>> or even more easy you can use LinqExtensionMethodAttribute to mark your >>>> extension and there specify the HQLFunction's name >>>> >>>> On Thu, Aug 19, 2010 at 11:56 PM, David Pfeffer <[email protected]>wrote: >>>> >>>>> How would I provide that? As far as I know, you'd have to use the >>>>> IHqlExpressionVisitor argument to the BuildHql method to "visit" that >>>>> argument of the extension method. Otherwise any expression passed to that >>>>> argument would not be evaluated. How would I specify the user type in this >>>>> instance? >>>>> >>>>> >>>>> On Thu, Aug 19, 2010 at 10:51 PM, Fabio Maulo <[email protected]>wrote: >>>>> >>>>>> In the implementation of of your Generator for your extension you can >>>>>> specify the IType. >>>>>> In this way you have a real LINQ extension working in RAM as it will >>>>>> work using NHibernate. >>>>>> >>>>>> If you are in a "safe-zone" where you can have the reference to >>>>>> NHibernate dll, you can use any other query-system provided by >>>>>> NHibernate, >>>>>> you don't need LINQ. >>>>>> >>>>>> >>>>>> On Thu, Aug 19, 2010 at 11:46 PM, David Pfeffer >>>>>> <[email protected]>wrote: >>>>>> >>>>>>> I've seen this blog post but I'm not sure how it applies. I'm aware >>>>>>> of how you'd implement ExampleMethod but not how you'd specify the user >>>>>>> type >>>>>>> for mapping of ExampleType. >>>>>>> >>>>>>> >>>>>>> On Thu, Aug 19, 2010 at 10:44 PM, Fabio Maulo >>>>>>> <[email protected]>wrote: >>>>>>> >>>>>>>> >>>>>>>> http://fabiomaulo.blogspot.com/2010/07/nhibernate-linq-provider-extension.html >>>>>>>> >>>>>>>> >>>>>>>> On Thu, Aug 19, 2010 at 11:41 PM, David Pfeffer < >>>>>>>> [email protected]> wrote: >>>>>>>> >>>>>>>>> That might work for instances of direct comparison, but what of an >>>>>>>>> extension method where the arguments are different... for example this >>>>>>>>> theoretical method: >>>>>>>>> >>>>>>>>> public static bool ExampleMethod(this int x, ExampleType y) { ... } >>>>>>>>> >>>>>>>>> In this example you have a usage but the usage isn't going to help >>>>>>>>> you guess the mapping type for ExampleType. The only way I can think >>>>>>>>> of >>>>>>>>> doing that is with the extension method patch. If you have another >>>>>>>>> idea I'd >>>>>>>>> be excited to hear it though. Otherwise would that be an acceptable >>>>>>>>> solution >>>>>>>>> and should I go ahead with it? >>>>>>>>> >>>>>>>>> >>>>>>>>> On Thu, Aug 19, 2010 at 9:58 PM, Fabio Maulo <[email protected] >>>>>>>>> > wrote: >>>>>>>>> >>>>>>>>>> ExpressionParameterVisitor >>>>>>>>>> NHibernateUtil.GuessType(expression.Type) >>>>>>>>>> >>>>>>>>>> We can't guess the type without the "usage context". >>>>>>>>>> myClass.MyProperty == something >>>>>>>>>> >>>>>>>>>> to really guess/know the type of "something" we have to know the >>>>>>>>>> mapping of "MyProperty". >>>>>>>>>> >>>>>>>>>> We may have an ugly patch-extension method where the user can >>>>>>>>>> specify the NH's IType but... well... that will be a patch not a >>>>>>>>>> solution. >>>>>>>>>> >>>>>>>>>> On Thu, Aug 19, 2010 at 3:46 PM, David Pfeffer < >>>>>>>>>> [email protected]> wrote: >>>>>>>>>> >>>>>>>>>>> Right, which is exactly what I'm working on right now... >>>>>>>>>>> >>>>>>>>>>> What I'm proposed is a fix for the issues relating to the LINQ >>>>>>>>>>> provider custom types. What do you all think of the solution? >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> On Thu, Aug 19, 2010 at 11:41 AM, Fabio Maulo < >>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>> >>>>>>>>>>>> I think that first we have to fix issues related to >>>>>>>>>>>> Linq-Provider and custom-types then we have to add some >>>>>>>>>>>> linq-extensions >>>>>>>>>>>> inside NHibernate-Spatial (as it has HQL extensions). >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> On Thu, Aug 19, 2010 at 11:02 AM, David Pfeffer < >>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>> >>>>>>>>>>>>> An example from NH Spatial -- >>>>>>>>>>>>> >>>>>>>>>>>>> I have a type... >>>>>>>>>>>>> >>>>>>>>>>>>> public class Breadcrumb >>>>>>>>>>>>> { >>>>>>>>>>>>> public virtual int Id { get; set; } >>>>>>>>>>>>> public virtual IGeometry Position { get; set; } >>>>>>>>>>>>> public virtual string Description { get; set; } >>>>>>>>>>>>> } >>>>>>>>>>>>> >>>>>>>>>>>>> ...and in my code I do the following... >>>>>>>>>>>>> >>>>>>>>>>>>> IGeometry center; >>>>>>>>>>>>> // code here to set the center to a useful point >>>>>>>>>>>>> var breadcrumbsWithinDistance = >>>>>>>>>>>>> session.Query<Breadcrumb>().Where(x => >>>>>>>>>>>>> x.Position.Distance(center) < 500); >>>>>>>>>>>>> >>>>>>>>>>>>> Now, how would the LINQ engine know the mapping of *center*? >>>>>>>>>>>>> Since it isn't a property of a mapped class there's nothing >>>>>>>>>>>>> already >>>>>>>>>>>>> specified here for what user type to use. >>>>>>>>>>>>> >>>>>>>>>>>>> I propose that line could be replaced as... >>>>>>>>>>>>> >>>>>>>>>>>>> var breadcrumbsWithinDistance = >>>>>>>>>>>>> session.Query<Breadcrumb>().Where(x => >>>>>>>>>>>>> x.Position.Distance(center.AsUserType(new >>>>>>>>>>>>> NHibernate.Type.CustomType(typeof(NHibernate.Spatial.Type.MsSql2008GeographyType), >>>>>>>>>>>>> null) >>>>>>>>>>>>> )) < 500); >>>>>>>>>>>>> >>>>>>>>>>>>> (or whatever other user type is appropriate for that database >>>>>>>>>>>>> engine) >>>>>>>>>>>>> >>>>>>>>>>>>> What do you think? >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> On Mon, Aug 16, 2010 at 5:16 PM, Fabio Maulo < >>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> El 16/08/2010, a las 12:14, David Pfeffer < >>>>>>>>>>>>>> [email protected]> escribió: >>>>>>>>>>>>>> >>>>>>>>>>>>>> I would attempt to write a fix, but this isn't just a bug. >>>>>>>>>>>>>> There's a design issue to be resolved here as to how to go about >>>>>>>>>>>>>> implementing this. >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> I'm not so sure about " a design issue"... >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> One idea I have is to create an extension method, >>>>>>>>>>>>>> WithUserType(this object obj, IType type) that will be used to >>>>>>>>>>>>>> inform the >>>>>>>>>>>>>> LINQ provider as to the type (UserType, etc.). >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> Try to write an example where the Type can't be inferred. >>>>>>>>>>>>>> Thanks. >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> If this sounds like a good idea, would anyone be able to >>>>>>>>>>>>>> provide a few pointers as to where to look to hook this in? I >>>>>>>>>>>>>> will take a >>>>>>>>>>>>>> look and see if I can patch. >>>>>>>>>>>>>> >>>>>>>>>>>>>> Thanks. >>>>>>>>>>>>>> >>>>>>>>>>>>>> On Mon, Aug 16, 2010 at 10:53 AM, Fabio Maulo >>>>>>>>>>>>>> <<[email protected]> >>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>> >>>>>>>>>>>>>>> Known issue >>>>>>>>>>>>>>> <http://216.121.112.228/browse/NH/component/10120> >>>>>>>>>>>>>>> http://216.121.112.228/browse/NH/component/10120 >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> On Fri, Aug 13, 2010 at 2:54 PM, David Pfeffer >>>>>>>>>>>>>>> <<[email protected]> >>>>>>>>>>>>>>> [email protected]> wrote: >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Hello all, >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> So I'm having a bit of difficulty trying to build a LINQ to >>>>>>>>>>>>>>>> NH Spatial provider. Specifically, I have not found a way to >>>>>>>>>>>>>>>> specify the >>>>>>>>>>>>>>>> user type for IGeometry types. So, even though I have the >>>>>>>>>>>>>>>> backend LINQ >>>>>>>>>>>>>>>> parser code plugged in, queries fail due to "No persister for: >>>>>>>>>>>>>>>> GeoAPI.Geometries.IGeometry." >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> In Criteria and HQL specifying the user type is easy. How do >>>>>>>>>>>>>>>> I specify the user type for a LINQ query so that my backend >>>>>>>>>>>>>>>> code is invoked? >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Thanks! >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>> Fabio Maulo >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> -- >>>>>>>>>>>> Fabio Maulo >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> -- >>>>>>>>>> Fabio Maulo >>>>>>>>>> >>>>>>>>>> >>>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> -- >>>>>>>> Fabio Maulo >>>>>>>> >>>>>>>> >>>>>>> >>>>>> >>>>>> >>>>>> -- >>>>>> Fabio Maulo >>>>>> >>>>>> >>>>> >>>> >>>> >>>> -- >>>> Fabio Maulo >>>> >>>> >>> >> >> >> -- >> Fabio Maulo >> >> >
