从两个不同的表中获取linq union中的选定记录

时间:2015-09-29 14:17:52

标签: c# sql linq lambda

我有两个表,UserNotificationsGlobalNotifications。我需要Union将这两个表放在一起并按日期排序以检索用户通知历史记录。这是我目前的工作查询:

var q = db.UserNotifications.Where(c => c.UserID == forUser.ScirraUserID)
    .Select(c => new {c.ID, type = "u", date = c.FirstDate})
    .Union(db.GlobalNotifications.Select(c => new {c.ID, type = "g", date = c.Date}))
    .OrderBy(c => c.date)
    .Skip(skip)
    .Take(take);

问题是,我无法解决这个问题,可能会将结果中的UserNotificationsGlobalNotifications记录返回到它们的类型和ID,这将需要对数据库进行另一次查询检索。

1 个答案:

答案 0 :(得分:2)

public enum NotificationType { User, Global }

public class mytype {
public int ID {get;set;}
public NotificationType type {get;set;}
public DateTime FirstDate {get;set;}
public UserNotification un {get;set;}
public GlobalNotification gn {get;set;}
}

var q = db.UserNotifications.Where(c => c.UserID == forUser.ScirraUserID)
    .Select(c => new mytype {c.ID, type = NotificationType.User, date = c.FirstDate, un=c, gn=null})
    .Union(db.GlobalNotifications.Select(c => new mytype {c.ID, type = NotificationType.Global, date = c.Date, un=null, gn=c }))
    .OrderBy(c => c.date)
    .Skip(skip)
    .Take(take);

或者您可以测试以查看un,gn中的哪一个为null并跳过类似的类型:

var q = db.UserNotifications.Where(c => c.UserID == forUser.ScirraUserID)
    .Select(c => new mytype {c.ID, date = c.FirstDate, un=c, gn=null})
    .Union(db.GlobalNotifications.Select(c => new mytype {c.ID, date = c.Date, un=null, gn=c }))
    .OrderBy(c => c.date)
    .Skip(skip)
    .Take(take);

或者,如果UserNotification和GlobalNotification都有共同的祖先(Notification)或接口(INotification?),那么也许使用和转换为。

如果您使用的是LINQ2SQL,则可能需要执行此操作:

var q = db.UserNotifications
    .Where(c => c.UserID == forUser.ScirraUserID)
    .ToList()
    .Select(c => new mytype {
        c.ID, 
        type = NotificationType.User, 
        date = c.FirstDate, 
        un=c, 
        gn=null})
    .Concat(
        db.GlobalNotifications
            .Select(c => new mytype {
                c.ID, 
                type = NotificationType.Global, 
                date = c.Date, 
                un=null, 
                gn=c })
            .ToList())
    .OrderBy(c => c.date)
    .Skip(skip)
    .Take(take);

尝试2:

var q1 = db.UserNotifications
    .Where(c => c.UserID == forUser.ScirraUserID)
    .OrderBy(c => c.FirstDate)
    .Select(c => new mytype {
        c.ID, 
        type = NotificationType.User, 
        date = c.FirstDate, 
        un=c, 
        gn=null})
    .Take(skip+take)
    .ToList();
var q2=db.GlobalNotifications
    .OrderBy(c => c.Date)
    .Select(c => new mytype {
        c.ID, 
        type = NotificationType.Global, 
        date = c.Date, 
        un=null, 
        gn=c })
    .Take(skip+take)
    .ToList();
var r=q1.Concat(q2)
    .OrderBy(c => c.FirstDate)
    .Skip(skip)
    .Take(take);