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
>
>

Reply via email to