Cześć.
Mając poniższy model:
public class Entity<T> where T : Entity<T>
{
public virtual int Id { get; set; }
public override bool Equals(object obj)
{
return Equals(obj as T);
}
private bool Equals(T rhs)
{
if(rhs == null)
return false;
if(IsTransient() && rhs.IsTransient())
return ReferenceEquals(this, rhs);
return Id == rhs.Id;
}
private int? _hashCode;
public override int GetHashCode()
{
if(!_hashCode.HasValue)
_hashCode = IsTransient() ? base.GetHashCode() : Id;
return _hashCode.Value;
}
private bool IsTransient()
{
return Id == default(int);
}
public static bool operator ==(Entity<T> lhs, Entity<T> rhs)
{
return Equals(lhs, rhs);
}
public static bool operator !=(Entity<T> lhs, Entity<T> rhs)
{
return !Equals(lhs, rhs);
}
}
public class Entry : Entity<Entry>
{
public virtual ISet<Comment> Comments { get; set; }
public Entry()
{
Comments = new HashSet<Comment>();
}
}
public class Question : Entry
{
public virtual ISet<QuestionRevision> QuestionRevisions { get; set; }
public virtual ISet<Answer> Answers { get; set; }
public Question()
{
QuestionRevisions = new HashSet<QuestionRevision>();
Answers = new HashSet<Answer>();
}
}
public class Revision : Entity<Revision>
{
public virtual DateTime CreatedAt { get; set; }
public virtual User User { get; set; }
public virtual string Content { get; set; }
}
public class QuestionRevision : Revision
{
public virtual string Title { get; set; }
public virtual ISet<Tag> Tags { get; set; }
public QuestionRevision()
{
Tags = new HashSet<Tag>();
}
}
public class Tag : Entity<Tag>
{
public virtual string Name { get; set; }
public virtual ISet<QuestionRevision> QuestionRevisions { get; set; }
public Tag()
{
QuestionRevisions = new HashSet<QuestionRevision>();
}
}
Chce napisać zapytanie wyciągające wszystkie pytania, których ostatnia zmiana zawiera tag o danej nazwie.
Na razie naskrobałem coś takiego:
var fxxx =
from question in session.Query<Question>()
from revision in
(from rev in question.QuestionRevisions
where rev == (from r in question.QuestionRevisions
orderby r.CreatedAt descending
select r).FirstOrDefault()
select rev)
where revision.Tags.Any(t => t.Name == "Foo")
select question;
I wydaje się działać, jednak jest trochę skomplikowane i mało czytelne. Ktoś ma jakiś lepszy pomysł na zrobienie tego? Może coś innego jest skopane i dlatego tak słabo wygląda to zapytanie?