根据另一个IQueryable的值排序IQueryable
本文关键字:IQueryable 排序 另一个 | 更新日期: 2023-09-27 18:10:55
我有两个IQueryables从Linq返回到SQL,我想按另一个排序。这就是我要写的
public class From
{
public int ID { get; set; }
public string Name { get; set; }
}
public class Message
{
public int FromID { get; set; }
public string Subject { get; set; }
public DateTime SentDate { get; set; }
}
public class MetaMsg
{
public string FromName { get; set; }
public string Subject { get; set; }
public DateTime SentDate { get; set; }
}
我想返回一个由From.Name
, Subject
或SentDate
排序的10个Message
对象的列表
我现在能做到这一点的唯一方法是从数据库中返回所有Message
和From
对象,并手动将它们组合成一个元对象,就像这样
List<MetaMsg> list = new List<MetaMsg>();
var froms = db.From.Where(//etc).ToList();
var messages = db.Message.Where(//bla bla).ToList();
foreach(Message m in messages)
{
MetaMsg mm = new MetaMsg {
Subject = m.Subject,
SentDate = m.SentDate
FromName = froms.Where(f = f.ID == m.FromID).FirstOrDefault().Name
};
list.Add(mm);
}
if(//sort by subject)
{
list = list.OrderBy(x => x.Subject).Take(10).ToList();
}
else if(//sort by date)
{
list = list.OrderBy(x => x.SentDate).Take(10).ToList();
}
else
{
list = list.OrderBy(x => x.FromName).Take(10).ToList();
}
是否有一种方法可以做到这一点,而不返回Message
和From
的完整列表?
这里有一个更好的解释,我想在弗兰肯代码中做什么(不完全是伪代码,也不是真正的代码)
List<MetaMsg> list = new List<MetaMsg>();
// get a list of 'From's, ordered by name
var froms = db.From.Where(//etc).OrderBy(x => x.Name);
var messages = null;
if(//sort by subject)
{
// order by subject and take 10
messages = db.Messages.OrderBy(x => x.Subject).Take(10).ToList();
}
else if(//sort by date)
{
// order by date and take 10
messages = db.Messages.OrderBy(x => x.Subject).Take(10).ToList();
}
else // sort by from Name...
{
// try and select 10 successive messages which have the fromID
// of our first (sorted) from on the list
int i = 0;
while(messages.Count < 10)
{
// if i is greater than the number of items in from, stop!
if(i > from.Count)
break;
messages += db.Messages.Where(x => x.FromID == from[i].ID).Take(10).ToList();
// if we don't quite make 10, keep going with the next id
i++;
}
}
// now create our list of froms.
foreach(Message m in messages)
{
MetaMsg mm = new MetaMsg {
Subject = m.Subject,
SentDate = m.SentDate
FromName = froms.Where(f = f.ID == m.FromID).FirstOrDefault().Name
};
list.Add(mm);
}
这里的细微差别在于,第二个示例只选择了10个消息对象,而第一个示例必须选择所有消息对象才能按名称排序。
从技术上讲,我的第二个例子中的代码应该工作(我还没有尝试过),但我想知道是否有一个更优雅的方式做到这一点? 标题>您可以像这样直接投影到MetaMsg
:
var result = (from m in db.Messages
let fromName = (from f in db.From
where m.FromId == f.ID
select f.Name).FirstOrDefault()
/* If you have navigation properties setup, you may be able to do this */
let fromName = m.From.Name
orderby fromName
select new MetaMsg
{
Subject = m.Subject,
SentDate = m.SentDate,
FromName = fromName,
}).Take(10).ToList();