Reputation: 3106
I have a mapping that has two references to two other mappings.
Firstly, would I create sub-criteria or create aliases?
So I have:
Base.Property1
Base.Property2
Base.Reference1.Property1
Base.Reference1.Property2
Base.Reference2.Property1
Base.Reference2.Property2
I want to project my query to just these 6 properties.
I have managed to use Projections on a query on just one table, but I'm having difficulty when it comes to multiple tables.
would I do something like (for each reference):
criteria.CreateCrtieria(bla)
.SetProjection(Projections.ProjectionList()
.Add(/*Add projections*/))
.SetResultTransformer(Transformers.AliasToBean(type));
Or just create aliases and have projections on the original criteria like so:
criteria.CreateAlias("reference1", "r1").CreateAlias("reference2", "r2")
.SetProjection(Projections.ProjectionList()
.Add(Projections.Property("baseProperty1")
.Add(Projections.Property("r1.property1")
.Add(Projections.Property("r2.property2")) /*etc*/
.SetResultTransformer(Transformers.AliasToBean(baseType));
I don't know if the previous two ideas actually work - they don't seem to, but I don't know if that's because I've forgotten something or if they're along totally the wrong lines.
Thanks.
Upvotes: 0
Views: 386
Reputation: 3106
My solution ended up requiring me to write a new Transformer. I'm not going to paste the code because it's fairly long and at the moment quite hacky. But for anyone interested:
Rather than doing .Add(Projections.Property("r1.property1")
I did .Add(Projections.Property("r1.property1"), "SubType.Property1")
Then in the transformer the alias "SubType.Property1" has a tuple value associated with it. I split the alias up and construct a SubType, and for any aliases associated with it, do the same as what the existing transformer does (assign values to those properties on that type), and then finally set the subtype object as a value to the property on the base type.
It's probably completely against the concept of Projections but it works, and works quite well, considering it was hacked together in a couple of hours.
Upvotes: 0
Reputation: 1725
Using the CreateAlias methods on the Criteria API allow you to join across to your referenced objects and allow you to project out the properties.
You assign each referenced type an alias which you then use to access the properties of the referenced objects.
Also please be aware that you need to make sure the names of the properties in the object you are projecting into are an exact match in the projection list.
You can also specify the JoinType on the CreateAlias methods as well should you want to force a InnerJoin instead of a LeftJoin.
var query = session.CreateCriteria<Base>()
.CreateAlias("Base.Reference1","ref1")
.CreateAlias("Base.Reference2","ref2")
.SetProjection(
Projections.ProjectionList()
.Add(Projections.Property("Base.BaseProperty"),"DtoBaseProperty")
.Add(Projections.Property("ref1.property1"),"DtoProperty1")
.Add(Projections.Property("ref2.property2"),"DtoProperty2")
)
.SetResultTransFormer(Transformers.AliasToBean(typeof(ProjectionDto)))
.List<ProjectionDto>();
public class ProjectionDto{
public string DtoBaseProperty;
public string DtoProperty1;
public string DtoProperty2;
}
Upvotes: 1