NHibernate使用Linq或QueryOver将子实体投影到父属性中



也许这很简单,但我被它困住了,我没有找到任何关于如何做到这一点的答案。我有一个父实体用户与子实体操作的集合。这两个实体是用于UI的,它们是一种视图。下面是伪代码

public class User
{
   public int Id {get; set;}
   public IEnumerable<Operation> Operations {get; set;}
   public int TotalSuccessfulAccesses {get; set;} // not mapped to the database
   public int TotalFailedAccesses {get; set;}     // not mapped to the database
}
public class Operation
{
   public int Id {get; set; }
   public int UserId {get; set; } // FK
   public int NbSuccessfulAccesses {get; set; }
   public int NbFailedAccesses {get; set; }
}

我想做的是让用户在一次往返数据库的子集合中初始化totalsuccesfulaccess和totalfailedaccess。

对于每个用户,我们应该计算Sum(operation . nbsuccessfulaccess)Sum(operation . nbfailedaccess),并分别对 user进行投影。totalsuccesfulaccess user . totalfailedaccess .

我试着玩多条件和几个查询,但我不满意。我想知道是否有一种简单的方法可以用投影或其他方法来做。也许我错过了什么。

你有什么建议吗?

提前感谢您的帮助

我能够通过以下方式摆脱神奇的别名字符串:

UserViewModel userView = null;
Add(Projections.Sum<User>(x => operations.NbSuccessfulAccesses).WithAlias(() => userView.TotalSuccessfulAccesses))

您可能需要分离视图模型和域实体。我假设在您的领域中,您有一个User类,其中包含操作列表,并且这些实体相应映射。

你可以创建一个视图模型:

public class UserViewModel
{
    public int UserId { get; set; }
    public int TotalSuccessfulAccesses { get; set; }
    public int TotalFailedAccesses {get; set;}
}

使用iccriteria可以创建以下查询:

var criteria = Session.CreateCriteria(typeof(User));
criteria.CreateAlias("Operations", "operations", JoinType.LeftOuterJoin);
var projList = Projections.ProjectionList();
projList.Add(Projections.GroupProperty("Id"));
projList.Add(Projections.Sum("operations.NbSuccessfulAccesses"), "TotalSuccessfulAccesses"); 
projList.Add(Projections.Sum("operations.NbFailedAccesses"), "TotalFailedAccesses");
criteria.SetProjection(projList);
criteria.SetResultTransformer(Transformers.AliasToBean<UserViewModel>());
var ret = criteria.List<UserViewModel>();

根据您的需要创建视图模型,并相应地在投影列表中添加任何属性。

希望对你有帮助。

感谢Kay,我想出了以下翻译:

Operation operations = null;
var q = GetSession().QueryOver<User>().Where(u => u.AccessKeyId == accessKeyId)
                    .Left.JoinQueryOver(x => x.Operations, () => operations)
                    .Select(Projections.ProjectionList()
                        .Add(Projections.Sum<User>(x => operations.NbSuccessfulAccesses), "TotalSuccessfulAccesses"))
                        .Add(Projections.Sum<User>(x => operations.NbFailedAccesses), "TotalFailedAccesses"))
                    .TransformUsing(Transformers.AliasToBean<UserViewModel>()).List< UserViewModel >();

然而,我想知道是否有一种方法来摆脱魔术字符串"totalsuccessfulaccess"one_answers"totalfailedaccess"。

如果我用这样的东西

UserViewModel userView = null;
Add(Projections.Sum<User>(x => operations.NbSuccessfulAccesses),  () => userView.TotalSuccessfulAccesses)

NHibernate产生一个错误:

找不到属性userView的setter。在类'Domain.Query.UserViewModel'中' totalsuccessfulpermissions '

不为真,因为totalsuccessfulaccess属性有一个setter。

有什么想法吗?

谢谢