这是 Dictionaries 表的示例。
身份证 | 姓名 |
---|---|
1 | 英语 |
2 | 意大利语 |
在 Words 表中存在对 DictionaryID
的引用身份证 | 字典ID | 词 |
---|---|---|
1 | 1 | A |
2 | 1 | B |
3 | 2 | C |
我想要实现的目标是,如果在 Dictionaries 和 Words 表之间进行左连接的单个查询,结果是 Dictionaries 表中的所有字段,并且仅是 Words 表中的行数名为 WordNumber 的字段,如以下模型所示:
public class Dictionary
{
public long ID { get; set; }
[Collation("NOCASE")]
public string Name { get; set; }
[Ignore]
public long WordNumber { get; set; }
}
所以,目前我有一个函数可以根据要搜索的简单文本返回字典列表,并且该函数正在运行。
public async Task<List<Dictionary>> GetDictionariesForSearchAsync(string search)
{
await Init();
return await Database.Table<Dictionary>()
.Where(w => w.Name.ToLower().Contains(search.ToLower()))
.ToListAsync();
}
现在,对于每个字典,我用另一个函数读取单词数:
public async Task<long> GetRecordNumberForDictionary(long id)
{
long num = await Database.Table<Word>().Where(i => i.DictionaryId == id).CountAsync();
return num;
}
这样做我担心的是我将查询复制到数据库,并且通过单个查询我可以获得更有效的查询。问题是我找不到像
GroupBy
这样的函数来对 Words 进行分组和计数。
谢谢你William但是你的代码让我遇到了这个问题。
我想知道您是否尝试使用“GroupJoin”方法,该方法允许您执行左连接并根据特定键对结果进行分组。
在您的情况下,您希望按“DictionaryId”对“单词”表进行分组,并计算每组的单词数。
public async Task<List<Dictionary>> GetDictionariesForSearchAsync(string search)
{
await Init();
var dictionaries = await (
from dict in Database.Table<Dictionary>()
where dict.Name.ToLower().Contains(search.ToLower())
join wordGroup in
(
from word in Database.Table<Word>()
group word by word.DictionaryId into wordGroup
select new { DictionaryId = wordGroup.Key, WordCount = wordGroup.Count() }
)
on dict.ID equals wordGroup.DictionaryId into wordCounts
from wordCount in wordCounts.DefaultIfEmpty()
select new Dictionary
{
ID = dict.ID,
Name = dict.Name,
WordNumber = (wordCount != null) ? wordCount.WordCount : 0
}
).ToListAsync();
return dictionaries;
}