【问题标题】:Select entities by condition column and clarify it by many to many condition按条件列选择实体并通过多对多条件进行澄清
【发布时间】:2014-12-15 11:00:01
【问题描述】:

按条件列选择实体,并通过多对多条件明确

我遵循了类(实体)的结构:

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 或获取所有订单的条件:

  • 订单未标记为ForFavorites AND
  • 订单被标记为ForFavorites 并且一些用户在Order.Owner.Favorites 中?

相反的方式:

如何写QueryOver 或Criteria 来选择我收藏夹中Order.Owner 的所有订单?

--更新:添加 Fluent 映射

我的映射:

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

--update:添加一些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)

【问题讨论】:

  • 你能展示一下你想生成的SQL吗?
  • 我正在编辑帖子。

标签: nhibernate many-to-many criteria queryover


【解决方案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 的连接,因为它没有被使用(你说你希望所有Orders 都符合条件)。

您的第二个查询可能如下所示:

session.QueryOver<Order>()
    .JoinQueryOver(o => o.Owner)
    .JoinQueryOver<FavoriteOrderers>(u => u.FavoriteOrderers)
        .Where(fo => fo.UserId == userId)

【讨论】:

  • 感谢您的回复。你逼我解决。我正在使用您的解决方案来搜索我的自我。见下文。
【解决方案2】:

经过良好的响应后,我找到了解决方案,因为响应海报使用了自己的映射假设, 这在我的情况下是不对的,但可能会更好。

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

【讨论】:

    猜你喜欢
    • 2012-05-02
    • 2022-01-10
    • 2018-05-06
    • 2018-07-23
    • 2023-03-22
    • 2021-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多