Can I use NHibernate criteria to project an object and its child collection into a class?

I use NH Criteria to retrieve project objects and select fields in a custom class (a bit like projecting data on a ViewModel to display in an MVC view).

This is easy to do with ProjectionList:

var emailCriteria = mSession.CreateCriteria<Email>();
emailCriteria.SetProjection(
    Projections.ProjectionList()
        .Add(Projections.Property("Subject"), "Subject")
);
emailCriteria.SetResultTransformer(Transformers.AliasToBean<EmailDataModel>());
var result = emailCriteria.List<EmailDataModel>();

However, my object contains a collection, and I want to return it back, and project it as a collection into my custom class.

My domain model looks (in simplified form) as follows:

public class Email {
    public string Subject
    public List<EmailAttachment> Attachments
    etc...
}

public class EmailAttachment {
    public UploadedFile File
}

public class UploadedFile {
    public string Filename
    public UploadedFileData Data
}

public class UploadedFileData {
    public byte[] Data
}

Here are the “data model" classes that I want to project onto:

public class EmailDataModel {
    public string Subject
    public List<EmailAttachmentDataModel> Attachments
}

public class EmailAttachmentDataModel {
    public string Filename
    public byte[] Data
}

, , , " ?", , . .

, , ( UploadedFile.Filename UploadedFileData.Data) EmailAttachmentDataModel EmailDataModel.

, - EmailCriteria.CreateAlias, EmailCriteria.CreateQuery - , , .

, , , NH Criteria.

+3
1

, , NHibernate 3 QueryOver. :

//Declare entities
Email email = null;
EmailAttachment attachment = null;
UploadedFile file = null;
Byte[] fileData = null;

//Select data from parent and child objects
var results = mSession.QueryOver<QueuedEmail>(() => email)
   .JoinAlias(() => email.Attachments, () => attachment, JoinType.LeftOuterJoin)
   .JoinAlias(() => attachment.File, () => file, JoinType.LeftOuterJoin)
   .JoinAlias(() => file.Data, () => fileData, JoinType.LeftOuterJoin)
   .TransformUsing(Transformers.DistinctRootEntity)
   .List<Email>()

   //Loop through results projecting fields onto POCO
   .Select(x => new EmailDataModel()
   {
       Id = x.Id,
       Body = x.Body,
       AttachmentCount = x.Attachments.Count(),
       FromAddress = x.FromAddress,
       //Loop through child collection projecting fields onto POCO
       Attachments = x.Attachments.Select(attach => new EmailAttachmentDataModel()
       {
           Data = attach.File.Data.Data,
           Filename = attach.File.Filename,
           Id = attach.Id
       }).ToArray() //NB Now projecting this collection as an array, not a list
   }).ToArray();

. - , , ( - ).

?

  • , , .

  • , , ( , NH).

  • ( ), SELECT. Criteria, SELECT , . , , , ( - - ).

, , NHibernate. , !

+5

Source: https://habr.com/ru/post/1791646/


All Articles