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

时间:2011-04-26 20:25:58

标签: nhibernate linq-to-nhibernate nhibernate-projections queryover

也许这很简单,但我坚持下去,我没有找到任何关于如何做到的答案。我有一个父实体User,其中包含子实体Operations的集合。这两个实体仅用于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; }
}

我想要做的是在一次往返数据库的过程中从子集合中初始化具有TotalSuccesfulAccesses和TotalFailedAccesses的用户。

对于每个用户,我们应该计算 Sum(Operation.NbSuccessfulAccesses) Sum(Operation.NbFailedAccesse)并分别对 User.TotalSuccesfulAccesses <进行投影/ strong>和 User.TotalFailedAccesses

我尝试使用多标准和多个查询,但我对它不满意。我想知道是否有一种简单的方法可以用投影或其他方法来做到这一点。或许我错过了一些东西。

你会推荐什么?

先谢谢你的帮助。

3 个答案:

答案 0 :(得分:4)

我能够通过以下方式摆脱魔术别名字符串:

UserViewModel userView = null;

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

答案 1 :(得分:3)

您可能需要将视图模型与域实体分开。我假设您的域中有一个User类,其中包含一个Operation列表,并且相应地映射了这些实体。

然后您可以创建一个视图模型:

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

使用ICriteria,您可以创建以下查询:

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>();

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

希望有所帮助。

答案 2 :(得分:2)

感谢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 >();

但是我想知道是否有意思去掉魔法字符串“TotalSuccessfulAccesses”和“TotalFailedAccesses”。

如果我使用类似的东西

UserViewModel userView = null;

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

NHibernate产生错误:

无法在“Domain.Query.UserViewModel”类中找到属性“userView.TotalSuccessfulAccesses”的setter

这不正确,因为有一个TotalSuccessfulAccesses属性的设置器。

有什么想法吗?

由于