I have a simple model, consisting of a document that references one or more article using a reference object (this is because in the domain, we do not own the articles so we can only reference them).
I'm trying to write a query that lists the documents, printing the ID and a string consisting of a comma separated list of article numbers. For example:
ID ARTICLES
------------------
1 ACC, PE2,
2 ER0, AQ3, FEE
3 PE2
My problem is with selecting the comma separated list.
Here are the domain classes:
// 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; }
}
The article reference is a value object so it does not have an ID of its own.
This is the view model that represents an item in the result list:
public class DocumentListItemModel
{
public int Id { get; set; }
public string ArticleNumbers { get; set; }
public string ReceiveDate { get; set; }
}
And here's the query class I have come up with so far:
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; }
}
}
As you can see, I can't express the .Where
statement because there is no way of matching references to documents from a domain point of view. The references are value objects and therefore don't have an ID.
The question is: how do I fix the query to properly select the list of article numbers so I can use it in my string.Join
statement to make the comma separated string?
I think you are taking the definition of value object too literally. Assigning a surrogate identifier (identity column, Guid, etc.) to a value object does not make it any less of a value object. It's a value object because its equality is based its values, not its identity. This does not require that a value object cannot have an identity, and in practice it almost always has to.
Your application obviously has to be able to link a Document to a set of ArticleReferences and the best way to accomplish that is by adding an ID to ArticleReference.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With