У меня есть база данных со «словарем», подобным этому:
Id (INT) | Key (VARCHAR) | Value (VALUE) | ForeignKey (INT?)
------------------------------------------------------------
1 | foo | bar | 23
2 | bar | foo | NULL
3 | foobar | value | NULL
4 | foobar | othervalue | 47
Теперь я хочу получить все ключи и значения для указанного c внешнего ключа, но также все внешние ключи, которые имеют значение NULL. , так что результат выглядит так:
ForeignKey = 23: ForeignKey = 47:
foo | bar bar | foo
bar | foo foobar | othervalue
foobar | value
Первоначально я попробовал этот подход:
dbContext.Table
.Where(t => t.ForeignKey == 47 || t.ForeignKey == null)
, но это дает мне foobar
дважды.
Я тогда хотя о множественных запросах и объединении результатов:
var t1 = _dbContext.Table
.Where(t => t.ForeignKey == 47);
var t2 = _dbContext.Table
.Where(t => t.ForeignKey == null && !t1.Any(tt => tt.Key == t.Key));
var final = t1.Union(t2);
Это, похоже, работает, но создает это SQL (примерно), которое кажется чрезмерным с тремя SELECT, тремя WHERE и UNION
SELECT [t1].[Id], [t1].[Key], [t1].[Value], [t1].ForeignKey
FROM [Table] AS [t1]
WHERE [t1].[ForeignKey] = 47
UNION
SELECT [t2].[Id], [t2].[Key], [t2].[Value], [t2].ForeignKey
FROM [Table] AS [t2]
WHERE [t2].[ForeignKey] IS NULL AND NOT (EXISTS (
SELECT 1
FROM [Table] AS [t3]
WHERE ([t3].[ForeignKey] = 47) AND ([t3].[Key] = [t2].[Key])))
У меня просто внутреннее чувство, что "должен быть лучший путь" ... так, есть? Как получить ключи и значения для указанного внешнего ключа c, а также ключи, которые еще не получены, которые имеют значение NULL?