To all interested, I wrote a reusable/generic transformer that lets me
write type-safe code like:
Session.QueryOver<Tenant>()
.Select(x => x.Id, x => x.FirstName, x
=> x.LastName)
.UnderlyingCriteria.SetResultTransformer(new
PartialObjectTransformer<Tenant>(x => x.Id, x => x.FirstName, x =>
x.LastName))
.List<Tenant>()
The code for the transformer is as follows:
public class PartialObjectTransformer<T> : IResultTransformer
{
private readonly List<PropertyInfo> _properties;
public PartialObjectTransformer(params Expression<Func<T,
object>>[]
properties)
{
_properties = new List<PropertyInfo>();
foreach (var property in properties)
{
Expression body = property;
if (body is LambdaExpression)
{
body = ((LambdaExpression)body).Body;
}
switch (body.NodeType)
{
case ExpressionType.Convert:
_properties.Add((PropertyInfo)
((MemberExpression)
((UnaryExpression) body).Operand).Member);
break;
case ExpressionType.MemberAccess:
_properties.Add((PropertyInfo)
((MemberExpression)
body).Member);
break;
default:
throw new
InvalidOperationException();
}
}
}
public object TransformTuple(object[] tuple, string[] aliases)
{
var instance = Activator.CreateInstance(typeof(T));
for (var i = 0; i < tuple.Length; i++)
{
_properties[i].SetValue(instance, tuple[i],
null);
}
return instance;
}
public IList TransformList(IList collection)
{
return collection;
}
}
Disclaimer, I don't know if this is ideal or will work for you, but it
works on my box. :)
On May 9, 4:20 pm, Jim Geurts <[email protected]> wrote:
> Thanks for your help with this Richard. I look forward to see what
> comes in the future for easier aliases. In the mean time, I'll look
> into using a DTO and custom transformer that Ayende mentioned
> here:http://ayende.com/Blog/archive/2007/08/26/Partial-Object-Queries-With...
>
> Thanks again,
>
> Jim
>
> On May 9, 5:02 am, "Richard Brown \(gmail\)" <[email protected]>
> wrote:
>
>
>
>
>
> > Hi Jim,
>
> > > If the NH dev team recommendation
> > > is to use linq to cast the object array to the intended object type ...
>
> > That was a suggestion. If you want the mapped type, the recommendation
> > would be to retrieve it directly without projections:
>
> > Session.QueryOver<Tenant>()
> > ...
> > .List();
>
> > > Having the API return an object array, when it *knows* the type of object
> > > ...
> > > fail to see why queries with the QueryOver api and projections
> > > wouldn't use the same method that NH uses to populate full objects.
>
> > The API can't know which object you are wanting as soon as you use
> > projections. The API allows arbitrary projections, so all bets are off on
> > the return type.
>
> > Incidentally, while there's no restriction to prevent you trying to manually
> > create partial Tenant objects, projections/result-transformers are more
> > typically use to create arbitrary non-mapped types (e.g., DTOs), not mapped
> > types.
>
> > If you simply return the complete objects directly (without projections)
> > then the query will "use the same method that NH uses to populate full
> > objects."
>
> > > Also, I did try to use a ResultTransformer, but was unsuccessful:
>
> > You need to alias each of the projections. I gave it a try with the
> > QueryOver API, and there isn't an easy way of doing this yet. I'll have a
> > look at making it easier to alias so you can write:
>
> > Tenant tenantAlias = null;
> > Session.QueryOver<Tenant>()
> > .Select(list => list
> > .Select(t => t.FirstName).WithAlias(() => tenantAlias.FirstName)
> > .Select(t => t.LastName).WithAlias(() => tenantAlias.LastName))
> > .SetResultTransformer(Transformers.AliasToBean<Tenant>())
> > .List<Tenant>();
>
> > For now, your best bet is probably to write your own IResultTransformer, or
> > simply return the full objects.
>
> > I hope that helps.
>
> > Richard
>
> > --
> > You received this message because you are subscribed to the Google Groups
> > "nhusers" 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
> > athttp://groups.google.com/group/nhusers?hl=en.
>
> --
> You received this message because you are subscribed to the Google Groups
> "nhusers" 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
> athttp://groups.google.com/group/nhusers?hl=en.
--
You received this message because you are subscribed to the Google Groups
"nhusers" 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/nhusers?hl=en.