Let's assume that we've got following entity:
public class Customer
{
public virtual int Id { get; set; }
public virtual string FirstName { get; set; }
public virtual string LastName { get; set; }
}
In addition there is following extension method:
public static string GetCard(this Customer @this)
{
throw new InvalidOperationException("Use only in IQueryable");
}
Now, I want to perform this query:
var q = from c in this.Session.Query<Customer>()
select new { Id = c.Id, InfoCard = c.GetCard() };
I though that creating and registering following hql generator will be enough:
class GetCardGenerator : BaseHqlGeneratorForMethod
{
public GetCardGenerator()
{
SupportedMethods = new[]
{
ReflectionHelper.GetMethodDefinition(() => CustomerExtensions.GetCard(null))
};
}
public override HqlTreeNode BuildHql(MethodInfo method, Expression targetObject, ReadOnlyCollection<Expression> arguments, HqlTreeBuilder treeBuilder, IHqlExpressionVisitor visitor)
{
Expression<Func<Customer, Card>> definition = c => new Card
{
FirstName = c.FirstName,
LastName = c.LastName,
FullName = c.FirstName + " " + c.LastName
};
return visitor.Visit(definition);
}
}
Unfortunately exception NotSupportedException is thrown with message MemberInit. During investingation I found comment in Linq\Visitors\SelectClauseHqlNominator.cs that HQL does not support New and MemberInit expression.
My question is: is it possible to create method that will be used in select clause of LINQ query and will be used to create and fill DTO object?
UPDATE: I don't want to make IQueryable<Card> from IQueryable<Customer> but I'm looking for solution that allows me to extract Card from Customer in any place, e.g. I've got Order entity with reference to Customer, I'd like to invoke query like:
from o in this.Session.Query<Order>
select new { Amount = o.OrderAmount, Customer = o.Customer.GetCard() };