我有一些类定义具有关系的实体
Account
has many Conversations [IEnumerable<Conversation> Conversations]
Conversation
has many Participants [IEnumerable<Account> Participants]
has many Messages [IEnumerable<Message> Messages]
Message
has one Sender [Account Sender]
has one Conversation [Conversation Conversation]
我正在尝试编写一个LINQ查询,该查询返回按日期排序的对话列表,并包含相关的参与者和消息。
public async Task<List<Conversation>> FindAllByAccountIdAsync(Int32 id)
{
return await _Db.Conversations
.Where(c => c.Participants.Any(p => p.AccountId == id))
.Include(c => c.Participants)
.Include(c => c.Messages)
.ToListAsync();
}
这可以完成工作,但包含了我真正不需要的大量数据。
public async Task<List<Conversation>> FindAllByAccountIdAsync(Int32 id)
{
return await _Db.Conversations
.Where(c => c.Participants.Any(a => a.AccountId == id))
.Include(c => c.Participants.Select(a=> new
{
AccountId = a.AccountId,
Profile = new { FullName = a.Profile.FullName,
Email = a.Profile.Email
}
}))
// Only return the last message in
// Eventually I would not return an array with a single object but just the single object inside associated with the property LastMessageIn
.Include(c => c.Messages.OrderBy(m => m.Date).Select(m=> new
{
Body = m.Body,
SenderId = m.Sender.AccountId
}).Last())
.ToListAsync();
}
此脚本返回一英里长的异常
{&#34; message&#34;:&#34;发生错误。&#34;,&#34; exceptionMessage&#34;:&#34; Include路径表达式必须引用导航属性在类型上定义。使用虚线路径作为参考导航属性,使用Select运算符作为集合导航属性........}
我的思想抵制理解和学习LINQ我不知道它是否仅仅是我,但是很快就要求超出基本的查询和投射它突破了我的控制
有人有一些提示吗?
答案 0 :(得分:3)
我不确定我是否理解你的问题,但我相信你想要这样的事情:
public async Task<List<Conversation>> FindAllByAccountIdAsync(Int32 id)
{
return await _Db.Conversations
.Where(c => c.Participants.Any(p => p.AccountId == id))
.Include(c => c.Participants)
.Include(c => c.Messages)
.Select(c => new
{
Participants = c.Participants.Select(a=> new
{
AccountId = a.AccountId,
Profile = new { FullName = a.Profile.FullName,
Email = a.Profile.Email
}
},
//EDIT: using OrderByDescending and FirstOrDefault
Messages = c.Messages.OrderByDescending(m => m.Date).Select(m=> new
{
Body = m.Body,
SenderId = m.Sender.AccountId
}).FirstOrDefault())
//others properties here
}
.ToListAsync();
}
答案 1 :(得分:1)
您无法投放包含。包含只是渴望加载。输出在C#中不会改变。只有最初加载的数据量(即性能)会发生变化。
似乎你想要一个投影而不是急切的加载,这是完全不兼容的概念。
但是我无法理解你想要达到的目的是什么。
答案 2 :(得分:1)
public async Task<List<Conversation>> FindAllByAccountIdAsync(Int32 id)
{
return await _Db.Conversations
.Where(c => c.Participants.Any(p => p.AccountId == id))
.Include(c => c.Participants.Select(_=>_))
.Include(c => c.Messages.Select(_=>_))
.ToListAsync();
}
应该够了。