假设我们有以下实体:
public class Customer
{
public virtual int Id { get; set; }
public virtual string FirstName { get; set; }
public virtual string LastName { get; set; }
}
此外还有以下扩展方法:
public static string GetCard(this Customer @this)
{
throw new InvalidOperationException("Use only in IQueryable");
}
现在,我想执行这个查询:
var q = from c in this.Session.Query<Customer>()
select new { Id = c.Id, InfoCard = c.GetCard() };
我虽然创建和注册以下 hql 生成器就足够了:
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);
}
}
不幸的是,异常 NotSupportedException 与消息 MemberInit 一起引发。在投资过程中,我在 Linq\Visitors\SelectClauseHqlNominator.cs 中发现 HQL 不支持 New 和 MemberInit 表达式的评论。
我的问题是:是否可以创建将在 LINQ 查询的 select 子句中使用并用于创建和填充 DTO 对象的方法?
更新:我不想从 IQueryable<Customer> 制作 IQueryable<Card> 但我正在寻找允许我在任何地方从客户中提取卡的解决方案,例如,我有参考客户的订单实体,我'想调用如下查询:
from o in this.Session.Query<Order>
select new { Amount = o.OrderAmount, Customer = o.Customer.GetCard() };