Я думаю, что этот вопрос требует команды МИНУС.
Select distinct(order_id)
from {table_name}
MINUS
Select distinct(order_id)
from (table_name}
where status = 'Complete'
Вы можете взять выходные данные из этого SQL и использовать их для дальнейших запросов, при необходимости.
Вы могли считать набор ключей в другой экземпляр IEnumerable сначала, затем foreach по тому списку
System.Collections.Hashtable ht = new System.Collections.Hashtable();
ht.Add("test1", "test2");
ht.Add("test3", "test4");
List<string> keys = new List<string>();
foreach (System.Collections.DictionaryEntry de in ht)
keys.Add(de.Key.ToString());
foreach(string key in keys)
{
ht[key] = DateTime.Now;
Console.WriteLine(ht[key]);
}
В понятии я сделал бы:
Hashtable table = new Hashtable(); // ps, I would prefer the generic dictionary..
Hashtable updates = new Hashtable();
foreach (DictionaryEntry entry in table)
{
// logic if something needs to change or nog
if (needsUpdate)
{
updates.Add(key, newValue);
}
}
// now do the actual update
foreach (DictionaryEntry upd in updates)
{
table[upd.Key] = upd.Value;
}
Если Вы используете Словарь вместо Хеш-таблицы, так, чтобы тип ключей был известен, самый легкий способ сделать копию набора Ключей, чтобы избежать, чтобы это исключение было:
foreach (string key in new List<string>(dictionary.Keys))
Почему Вы получаете исключение, говоря Вам, что Вы изменили набор, которого Вы выполняете итерации, когда на самом деле Вы не имеете?
Внутренне, класс Хеш-таблицы имеет поле версии. Добавление, Вставьте и Удалите инкремент методов эта версия. При создании перечислителя на любом из наборов, которые выставляет Хеш-таблица, объект перечислителя включает текущую версию Хеш-таблицы. Метод MoveNext перечислителя проверяет версию перечислителя по Хеш-таблице, и если они не равны, это бросает InvalidOperationException, который Вы видите.
Это - очень простой механизм для определения, была ли Хеш-таблица изменена. На самом деле это немного слишком просто. Набор Ключей действительно должен поддержать свою собственную версию, и его метод GetEnumerator должен сохранить версию набора в перечислителе, не версию Хеш-таблицы.
Существуют другой, более тонкий дефект дизайна в этом подходе. Версия является Int32. Метод UpdateVersion не делает никакой проверки границ. Поэтому возможно при создании точно правильного количества модификаций к Хеш-таблице (2 раза Int32.MaxValue
, плюс-минус), для версии на Хеш-таблице и перечислителе, чтобы быть тем же даже при том, что Вы радикально изменили Хеш-таблицу начиная с создания перечислителя. Таким образом, метод MoveNext не выдаст исключение даже при том, что это должно, и Вы получите неожиданные результаты.
Вы не можете изменить набор объектов, сохраненных в наборе, в то время как Вы перечисляете по нему, так как это делает жизнь очень трудной для итератора в большинстве случаев. Рассмотрите случай, где набор представляет сбалансированное дерево и может подвергнуться вращениям после вставки. Перечисление не имело бы никакого вероятного способа отслеживать то, что оно видело.
Однако, если Вы просто пытаетесь обновить значение затем, можно записать:
deEntry.Value = sValue
Обновление значения здесь не оказывает влияния на перечислитель.
Самый простой путь состоит в том, чтобы скопировать ключи в отдельный набор, затем выполнить итерации через это вместо этого.
Вы используете.NET 3.5? Если так, LINQ делает вещи немного легче.
Это зависит от того, почему Вы - цикличное выполнение через объекты в хеш-таблице. Но Вы, вероятно, смогли бы выполнить итерации через ключи вместо этого. Так
foreach (String sKey in htSettings_m.Keys)
{ // Get value from Registry and assign to sValue.
// ...
// Change value in hashtable.
htSettings_m[sKey] = sValue;
}
Другая опция состоит в том, чтобы создать новый HashTable. Выполните итерации через первое при добавлении, что объекты к второму затем заменяют оригинал новым.
Цикличное выполнение через ключи требует меньшего количества объектных выделений все же.
private Hashtable htSettings_m = new Hashtable();
htSettings_m.Add("SizeWidth", "728");
htSettings_m.Add("SizeHeight", "450");
string sValue = "";
foreach (string sKey in htSettings_m.Keys)
{
// Get value from Registry and assign to sValue
// ...
// Change value in hashtable.
htSettings_m[sKey] = sValue;
}
Возможно, можно использовать Хеш-таблицу. Набор ключей? Перечисление через это могло бы быть возможным при изменении Хеш-таблицы. Но это - только предположение...
Ключевой частью является метод ToArray ()
var dictionary = new Dictionary<string, string>();
foreach(var key in dictionary.Keys.ToArray())
{
dictionary[key] = "new value";
}
Вот как я сделал это в словаре; сбрасывает каждое значение в dict на false:
Dictionary<string,bool> dict = new Dictionary<string,bool>();
for (int i = 0; i < dict.Count; i++)
{
string key = dict.ElementAt(i).Key;
dict[key] = false;
}