次のエンティティがあるとします。
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> を作成したくありませんが、任意の場所で Customer から Card を抽出できるソリューションを探しています。たとえば、Customer を参照する Order エンティティがあります。 '次のようなクエリを呼び出したい:
from o in this.Session.Query<Order>
select new { Amount = o.OrderAmount, Customer = o.Customer.GetCard() };