Скомпилированные выражения и шаблон спецификации (NHibernate)
Я использую IRepository для доступа к NHibernate, где хранилище предоставляет метод Find, который принимает спецификацию, но не может найти способ обработать спецификации, не передавая конкретные объекты, когда я на самом деле хочу передать только ID... Мой репозиторий реализован как это, с NHiberate за кулисами...
IEnumerable<T> FindAll(ISpecification spec)
Абстрактный класс, который я реализую, выглядит следующим образом:
/// <summary>
/// Defines an abstract specification with an expression, where the
/// expression is compiled when IsSatisfiedBy is invoked.
/// </summary>
/// <typeparam name="T">The type of object this specification supports.</typeparam>
public abstract class SpecificationWithExpressionBase<T> : ISpecificationWithExpression<T>
{
/// <summary>
/// Stores the compiled expression.
/// </summary>
private Func<T, bool> _compiledExpression;
/// <summary>
/// Gets a compiled expression.
/// </summary>
private Func<T, bool> CompiledExpression
{
get { return _compiledExpression ?? (_compiledExpression = SpecExpression.Compile()); }
}
/// <summary>
/// The expression of the specification.
/// </summary>
public abstract Expression<Func<T, bool>> SpecExpression { get; }
/// <summary>
/// Checks whether the object is satisfied by this specification.
/// </summary>
/// <param name="obj">The object to check.</param>
/// <returns>True if this object has been satisfied. False otherwise.</returns>
public bool IsSatisfiedBy(T obj)
{
return CompiledExpression(obj);
}
}
Если у меня тогда есть два класса...
class Member
{
public int Id { get; set; }
public Template Template { get; set; }
}
class Template
{
public int Id { get; set; }
}
... и я создаю две спецификации, чтобы выяснить, связан ли элемент с данным шаблоном, следующим образом:
class IsBoundToTemplateFailing : SpecificationWithExpressionBase<Member>
{
int _templateId;
public IsBoundToTemplate(int templateId)
{
_templateId = templateId;
}
public override Expression<Func<Member, bool>> SpecExpression
{
get { return s => s.Template.Id == _templateId; }
}
}
class IsBoundToTemplateSucceeding : SpecificationWithExpressionBase<Member>
{
Template _template;
public IsBoundToTemplate(Template template)
{
_template = template;
}
public override Expression<Func<Member, bool>> SpecExpression
{
get { return s => s.Template == template; }
}
}
При передаче спецификаций в репозиторий (реализован NHibernate) первый отказывает, в то время как другой завершается успешно, вероятно, потому что выражение компилируется.
NHibernate выбрасывает исключение, сказав cannot resolve property "Id" of the class "Template"
,
Можно ли построить спецификацию, чтобы можно было передавать идентификатор вместо экземпляра?