按条件列选择实体,并按多个条件澄清
我遵循了类(实体)的结构:
class Order {
...
public virtual long OrderId {get; set;}
public virtual boolean ForFavorites {get; set;}
public virtual User Owner {get; set;}
...
}
class User {
...
public virtual long UserId { get; set; }
public virtual List<User> Favorites {get; set;}
public virtual List<User> FavoritesOrderers {get; set;}
...
}
如何编写QueryOver
或Criteria以获取所有订单:
ForFavorites
AND ForFavorites
而某些用户在订单中.Owner.Favorites?相反的方式:
如何撰写QueryOver
或条件以选择我的收藏夹中Order.Owner
的所有订单?
- 更新:添加Fluent Mapping
我的映射:
class OrderMap:ClassMap<Order> {
public OrderMap(){
Id(x=>x.OrderId).GeneratedBy.Identity();
Map(x => x.ForFavorites);
References(x => x.Owner, "UserId");
...
}
}
class UserMap:ClassMap<User> {
public UserMap() {
Id(x => x.UserId).GeneratedBy.Assigned();
HasManyToMany(x => x.Favorites)
.AsBag()
.LazyLoad()
.Table("Favorites")
.ParentKeyColumn("UserId")
.ChildKeyColumn("FavoriteId")
.Cascade.All();
HasManyToMany(x => x.FavoritesOrderers)
.AsBag()
.LazyLoad()
.Table("FavoriteOrderers")
.ParentKeyColumn("UserId")
.ChildKeyColumn("FavoriteId")
.Cascade.All();
...
}
}
- 更新:添加一些SQL
SQL可能是这样的:
:userId
是收藏用户的ID
SELECT *
FROM [Order] o
JOIN [User] u ON o.owner = u.userId
WHERE (
(o.ForFavorites = false) ||
(o.ForFavorites = true && :userId IN
(SELECT favoriteId FROM [Favorites] f WHERE (f.UserId = u.userId))
))
是否有一些其他变体具有更好的性能?..
相反的方式:
SELECT *
FROM [Order] o
JOIN [User] u ON o.owner = u.userId
INNER JOIN [FavoriteOrderers] fo ON fo.favoriteId=u.userId
WHERE (fo.userId = :userId)
答案 0 :(得分:1)
我对你的映射做了一些假设,但希望这会有所帮助:
对于第一个查询,可能是这样的:
session.QueryOver<Order>()
.JoinQueryOver(o => o.Owner)
.Where(
Restrictions.Or(
Restrictions.Where<Order>(o => !o.ForFavorites),
Restrictions.And(
Restrictions.Where<Order>(o => o.ForFavorites),
Subqueries.In(
userId,
QueryOver.Of<Favorite>()
.Where(f => f.UserId = userId)
.Select(f => f.FavoriteId)
.DetachedCriteria))))
.List<Order>();
我将联接省略为User
,因为它未被使用(并且您说您希望所有Order
符合条件。
您的第二个查询可能如下所示:
session.QueryOver<Order>()
.JoinQueryOver(o => o.Owner)
.JoinQueryOver<FavoriteOrderers>(u => u.FavoriteOrderers)
.Where(fo => fo.UserId == userId)
答案 1 :(得分:1)
经过良好的回复,我发现了我的解决方案,因为在回复中海报使用自己的映射假设, 在我的情况下哪些不对,但可能会更好。
session.QueryOver<Order>()
.JoinAlias(o => o.Owner, () => owner)
.Where(
Restrictions.Or(
Restrictions.Where<Order>(o => !o.ForFavorites),
Restrictions.And(
Restrictions.Where<Order>(o => o.ForFavorites),
Subqueries.In(
userId,
QueryOver.Of<User>()
.Where(f => f.UserId = owner.UserId)
.JoinQueryOver<User>(u => u.Favorite, () => fav)
.Select(f => f.FavoriteId)
.DetachedCriteria))))
.List<Order>();