Hi Kurt,
For future reference, generally you can tell if your code has a chance of
being converted to an expression tree by examining the argument or return
signature. So for your example:
public string FullName{
get{
return string.Format("{0} {1}, FirstName, LastName");
}
}
Currently, there is no way to get an expression tree of that code. The code
you want converted to an expression tree has to be returned as an
Expression<T>. So there is no hope for the above example being converted to
SQL and being executed against the DB. A format that would have more of a
chance would look something like this:
public Expression<Func<Customer, string>> GetFullNameExpression = c =>
string.Format("{0} {1}, c.FirstName, c.LastName");
public string FullName
{
get { return GetFullNameExpression.Compile()(this); }
}
In the above example, the code for determining the full name is exposed as
an Expression<T> (where T is Func<Customer, string>). Now if you passed the
GetFullNameExpression to a method that was expecting an expression, that
method could potentially inspecting the expression and building a different
representation, such as a SQL query.
In summary, expression tree acrobatics are only possible if you are
returning or passing your code as an Expression<T>.
Paul Batum
On Thu, Jun 18, 2009 at 9:32 AM, Kurt Johnson <[email protected]> wrote:
>
> I think I got it. I missed the entire concept of persisting the
> property result as the end-game. I was expecting NHibernate.Linq to
> translate some expression tree of my FullName property into a criteria
> for me.
>
> I finally understand the concept, yet I am bit bummed. Maybe there is
> some futuristic alien race that has a library for my desired code-
> witchery (or, I can get cracking on my own patch).
>
> Disappointed but now back-on-board, I went ahead and mapped the above
> property FullName (after adding an empty setter) accordingly with a
> SetAttribute for "access" as "readonly".
>
> Now, my updates to my FirstName and LastName are persisting to the
> database the FullName column. Also, I am able to query that column in
> the database.
>
> Thanks again, Hudson. That was precisely what I needed!
>
> On Jun 17, 8:59 am, Hudson Akridge <[email protected]> wrote:
> > > It sounds like my virtual method needs to be mapped with a readonly
> >
> > accessor (?) so that it doesn't go out to via nhib in outgoing DDL,
> >
> > but can be interpreted by the HQL parser in selects. Am I on the right
> >
> > track?
> >
> > Yup, you're on the right track :) But it's the inbound nhib that you're
> > looking to avoid (the rehydration part) Basically the ReadOnlyAccessor
> > allows NHibernate to persist the value, but not retrieve it. However,
> that
> > value is stored in the database, and thus, available for HQL queries,
> which
> > is really just a DSL that sits on top of SQL.
> >
> > Think of it like this. If it's not available in SQL to write a query by
> > hand, then it's not available for HQL. ReadOnlyAccessor gives you the
> > optimization of saying that this property will only ever be queried on,
> so
> > persist it into the DB, but the DB is not used to evaluate the value in
> the
> > domain model.
> >
> >
> >
> > On Wed, Jun 17, 2009 at 8:55 AM, Kurt Johnson <[email protected]> wrote:
> >
> > > Thanks for the reply, Hudson.
> >
> > > I will take a look at the NHibernate docs and try and implement that.
> > > It sounds like my virtual method needs to be mapped with a readonly
> > > accessor (?) so that it doesn't go out to via nhib in outgoing DDL,
> > > but can be interpreted by the HQL parser in selects. Am I on the right
> > > track?
> >
> > > I was thinking that the conversion from Linq\POCO would occur first --
> > > via an expression tree -- then, translated to HQL as the concatention
> > > of the two fields.
> >
> > > So much to learn... and I love it.
> >
> > > Thanks again,
> > > Kurt
> >
> > > On Jun 16, 2:12 pm, Hudson Akridge <[email protected]> wrote:
> > > > Your question isn't specifically a fluent way that I'm aware of,
> you're
> > > just
> > > > looking for a way to map a model formula property to the database,
> for
> > > > querying, but that doesn't get read out of the database (because
> again,
> > > it's
> > > > calculated in the model based on the other two properties). Is that
> > > correct?
> > > > In NHibernate, look at mapping the FullName property using a:
> > > > access="NHibernate.Properties.ReadOnlyAccessor, NHibernate"
> >
> > > > Attribute. The ReadOnlyAccessor may be exactly what you want there.
> >
> > > > I don't have the source of fluent available to me right now, but I
> don't
> > > > believe we currently support the ReadOnlyAccessor, so you might be
> stuck
> > > > setting that manually with SetAttribute for now (although expect that
> > > method
> > > > to go away here soon in trunk), or you can just modify your version
> of
> > > FNH
> > > > to support that.
> >
> > > > On Tue, Jun 16, 2009 at 12:56 PM, kujotx <[email protected]> wrote:
> >
> > > > > I have a derived class that uses a method from a value object. My
> > > > > value object has first, last names, so I added a concatenation for
> > > > > full name and other variations for Find() criteria.
> >
> > > > > The abbreviated version is shown below. My goal is to be able to do
> > > > > something like the following p => p.Person.FullName.Contains("John
> > > > > Doe");
> >
> > > > > I am using Nhibernate.Linq and Linq.Specifications. I was trying to
> > > > > write a specification that included the
> >
> > > > > That fails. Is there a fluent nhibernate way that I can accomplish
> > > > > this, or will the solution lie more in nhibernate?
> >
> > > > > Thanks,
> >
> > > > > Kurt
> >
> > > > > <code>
> > > > > public class User : AbstractUser{
> > > > > }
> >
> > > > > public abstract AbstractUser
> > > > > {
> > > > > public virtual Person Person {get; private set:}
> > > > > }
> >
> > > > > public class Person{
> > > > > public virtual string LastName {get; private set;}
> > > > > public virtual string FirstName {get; private set;}
> >
> > > > > public Person (string firstName, string lastName){
> > > > > FirstName = firstName;
> > > > > LastName = lastName;
> > > > > }
> >
> > > > > public string FullName{
> > > > > get{
> > > > > return string.Format("{0} {1}, FirstName,
> > > > > LastName");
> > > > > }
> > > > > }
> > > > > }
> > > > > </code>
> >
> > > > --
> > > > - Hudsonhttp://www.bestguesstheory.comhttp://
> twitter.com/HudsonAkridge
> >
> > --
> > - Hudsonhttp://www.bestguesstheory.comhttp://twitter.com/HudsonAkridge
> >
>
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"Fluent NHibernate" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/fluent-nhibernate?hl=en
-~----------~----~----~----~------~----~------~--~---