Mam prosty model, składający się z dokumentu, który odwołuje się do jednego lub więcej artykułów za pomocą obiektu odniesienia (dzieje się tak dlatego, że w domenie nie jesteśmy jej właścicielami artykuły, abyśmy mogli je tylko odwoływać).Jak wybrać i spożyć zbiór obiektów wartości w kwerendzie NHibernate QueryOver
Próbuję napisać zapytanie zawierające listę dokumentów, drukowanie identyfikatora i ciąg złożony z rozdzielanej przecinkami listy numerów artykułów. Na przykład:
ID ARTICLES
------------------
1 ACC, PE2,
2 ER0, AQ3, FEE
3 PE2
Mój problem polega na wybraniu z listy oddzielonych przecinkami.
Oto klas domeny:
// The Entity class has an Id property.
public class Document : Entity
{
public virtual IEnumerable<ArticleReference> ArticleReferences { get; set; }
public virtual DateTime ReceiveDate { get; set; }
}
// The ValueObject does not have an Id property ofcourse.
public class ArticleReference : ValueObject
{
public virtual string ArticleNumber { get; set; }
public virtual string ArticleName { get; set; }
}
Odniesienie artykuł jest obiektem wartość więc nie ma identyfikatora własnych.
Jest to model widoku, który reprezentuje pozycję na liście wyników:
public class DocumentListItemModel
{
public int Id { get; set; }
public string ArticleNumbers { get; set; }
public string ReceiveDate { get; set; }
}
A oto klasa zapytania mam wymyślić do tej pory:
public class DocumentQuery
{
public IList<DocumentListItemModel> ExecuteQuery()
{
IntermediateModel model = null;
ArticleReference articleReferenceAlias = null;
return Session
.QueryOver<Document>()
.JoinAlias(n => n.ArticleReferences,() => articleReferenceAlias);
.SelectSubQuery(
QueryOver.Of<ArticleReference>(() => articleReferenceAlias)
// There is no way of matching references to documents from a domain
// point of view since the references are value objects and
// therefore don't have an ID.
.Where(n => ...)
.Select(q => articleReferenceAlias.Number))
.WithAlias(() => model.ArticleNumbers)
.TransformUsing(Transformers.AliasToBean<IntermediateModel>());
.Future<IntermediateModel>()
.ToList()
.Select(n =>
new DocumentListItemModel()
{
Id = n.Id,
ArticleNumbers = string.Join(", ", n.ArticleNumbers.OrderBy(p => p)),
ReceiveDate = n.ReceiveDate.ToString("d", CultureInfo.CurrentCulture)
})
.ToList();
}
private class IntermediateModel
{
public int Id { get; set; }
public IEnumerable<string> ArticleNumbers { get; set; }
public DateTime ReceiveDate { get; set; }
}
}
Jak widać, Nie mogę wyrazić instrukcji .Where
, ponieważ nie ma możliwości dopasowania odniesień do dokumentów z punktu widzenia domeny. Odwołania są obiektami wartości i dlatego nie mają identyfikatora.
Pytanie brzmi: jak to naprawić zapytania prawidłowo wybrać listę artykułów, dzięki czemu można go używać w moim string.Join
oświadczeniem aby oddzielone przecinkami ciąg?
Czy próbowałeś dodać publiczne int? DocumentId {get; set;} to ArticleReference? ps nie są właściwościami, które mają być wirtualne w nhibernate –
Masz rację co do wirtualnych, zaktualizowałem moje pytanie. Zapomniałem o nich pisząc kod pojęciowy (prawdziwy kod jest zbyt rozpraszający ze względu na jego rozmiar). Odnośnie dodawania DocumentId do ArticleReference: byłoby to sprzeczne z całą ideą obiektów wartościowych, skutecznie przekształcając ją w podmiot. –
prawda - ale z powodu takich problemów mam tendencję do posiadania osobnego modelu domeny do mojego modelu aplikacji, więc dodam funnie, takie jak dodanie właściwości parentid do elementu podrzędnego. –