gpt4 book ai didi

collections - 我可以使用 NHibernate Criteria 将实体及其子集合投影到类上吗?

转载 作者:行者123 更新时间:2023-12-01 11:57:59 26 4
gpt4 key购买 nike

我正在使用 NH Criteria 来检索实体并将选择性字段投影到自定义类上(有点像将数据投影到 ViewModel 以在 MVC View 上显示)。

这很容易使用 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>();

但是,我的实体包含一个集合,我也想将其带回来,并将其作为集合投影到我的自定义类中。

我的域模型看起来(以简化形式)是这样的:

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
}

这是我想要投影到的“数据模型”类:

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 查询的人都是一个有用的练习。

最佳答案

好的,我想我已经解决了升级到 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,并为链下游的子代生成更多。如果您处理的是小数字,那很好,但如果您可能会返回数千行(就像我在本例中那样 - 它是电子邮件引擎的 Web 服务),那很好。

  • 我希望这对希望进一步深入 NHibernate 查询的任何人都有用。就我个人而言,我很高兴我现在可以继续我的生活!

    关于collections - 我可以使用 NHibernate Criteria 将实体及其子集合投影到类上吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4977038/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com