簡體   English   中英

如何在子集合的Nhibernate中執行QueryOver

[英]How to do a QueryOver in Nhibernate on child collection

您好我有一個名為Notifications的類,它是User的子類。

public class User
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string UserName { get; set; }
    public ICollection<UserNotification> UserNotifications { get; set; }
}

public class Notification
{
    public int Id { get; set; }
    public ICollection<UserNotification> UserNotifications { get; set; }
    public string Title { get; set; }
    public string Message { get; set; }
    public bool IsRead { get; set; }
    public DateTime CreatedDate { get; set; }
}

public class UserNotification
{
    public User User { get; set; }
    public Notification Notification { get; set; }
}

現在我想獲取User By ID,它將為當前用戶提供所有通知。

var user = NhSession.Get<User>(userId);

但我不想收到所有通知。 我只想讓用戶獲得未讀通知,並且只想獲得用戶的top 5 (Latest) notifications

我嘗試通過joinQueryOver實現這一點,但我無法做到這一點。 任何人都可以建議讓這個工作。

基於最新的更新和新的Entity(ies)結構,我們現在可以從Pairing對象中獲利,並快速選擇具有未讀Notificaitons的用戶

查找尚未閱讀通知的用戶

var session = NHSession.GetCurrent();
Notification notification = null;
UserNotification pair = null;
User user = null;

var subquery = QueryOver.Of<UserNotification>(() => pair)
    // this will give us access to notification
    // see we can filter only these which are NOT read
    .JoinQueryOver(() => pair.Notification, () => notification)
    // here is the filter
    .Where(() => !notification.IsRead)
    // now the trick to take only related to our user
    .Where(() => pair.User.Id == user.Id)
    // and get the user Id
    .Select(x => pair.User.Id);

var listOfUsers = session.QueryOver<User>(() => user)
    .WithSubquery
        .WhereProperty(() => user.Id)
        .In(subquery)
    // paging
    .Take(10)
    .Skip(10)
    .List<User>();

每個userId查找5個未讀通知

var userId = 1;
var subqueryByUser = QueryOver.Of<UserNotification>(() => pair)
    // now we do not need any kind of a join 
    // just have to filter these pairs related to user
    .Where(() => pair.User.Id == userId)
    // and get the notification Id
    .Select(x => pair.Notification.Id);

var notificationsPerUser = session.QueryOver<Notification>(() => notification)
    .WithSubquery
        .WhereProperty(() => notification.Id)
        .In(subqueryByUser)
    .Where(() => !notification.IsRead)
    // if needed we can order
    // .OrderBy(...
    .Take(5)
    .List<Notification>()

session.Get<TEntity>(entityId)用於我們加載實體AS IS映射。 這是合同。

如果我們想要獲得過濾結果,我們必須使用另一個合同來重新獲取數據: Session.CreateCriteria() (或任何其他查詢API,即QueryOver()

所以在我們的例子中,我們應該構建查詢以查找具有未讀通知的用戶:

Occupation Notification= null;
User user = null;

var subquery = QueryOver.Of<Notification>(() => notification) 
    .Where(() => !notification.IsRead )
    // just related to the user, from outer query
    .Where(() => notification.User.ID == user.ID)
    .Select(x => notification.User.ID);

var list = session.QueryOver<User>(() => user)
    .WithSubquery
        .WhereProperty(() => user.ID)
        .In(subquery)
    // paging
    .Take(10)
    .Skip(10)
    .List<User>();

我們在這里看到的是通知(實際上是必須的)通知已經向用戶提及其父級:

public class Notification
{
    ...
    public User User {get;set;}
}

但這應該不是問題,它只是一個映射,而不是DB的變化

類似的查詢(在通知之上)我們可以使用它們只獲得前5個:

var notifications = session.QueryOver<Notification>(() => notification)
    // here is a userId for a specific user.
    // we can use IN() to load for more of them
    .Where(() => notification.User.ID != userId)
    .Take(5)
    .List<Notification>()
;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM