Бросать исключения с Linq - PullRequest
4 голосов
/ 24 февраля 2012

Я объединяю 2 в коллекции памяти

var items = 
    from el in elements 
    join def in Cached.Elements() 
        on el.Value equals def.Name into temp1
    from res in temp1.DefaultIfEmpty()                        
    select new
    {
        el.NodeType, 
        res.DefKey, 
        res.DefType, 
        res.BaseKey, 
        el.Value 
    };

Однако, в идеале, если один из элементов не может быть найден, я хотел бы вызвать исключение, что-то вроде

throw new System.Exception(el.Value + " cannot be found in cache!");

Я смотрел на System.Interactive, который предлагает метод расширения Catch, но я не уверен, как ссылаться на текущий 'el' в этом контексте.Так, например, мне было интересно что-то вроде

    var items = (
        from el in elements 
        join def in Cached.Elements() 
            on el.Value equals def.Name into temp1
        from res in temp1.DefaultIfEmpty()                        
        select new 
        { 
            el.NodeType, 
            res.DefKey, 
            res.DefType, 
            res.BaseKey, 
            el.Value 
        })
        .ThrowIfEmpty();

, но, istm, это повлечет за собой передачу всего набора в метод расширения, а не вызовет исключение при обнаружении пропущенного значения.1011 * В качестве альтернативы, я мог бы заменить DefaultIfEmpty на ThrowIfEmpty

    var items = (
        from el in elements 
        join def in Cached.Elements() 
            on el.Value equals def.Name into temp1
        from res in temp1.ThrowIfEmpty()                        
        select new 
        { 
            el.NodeType, 
            res.DefKey, 
            res.DefType, 
            res.BaseKey, 
            el.Value 
        });

Есть ли «правильный» / лучший способ сделать это?

Ответы [ 2 ]

2 голосов
/ 24 февраля 2012

Вы можете использовать GroupJoin. Нечто подобное должно работать у вас:

elements.GroupJoin(Cached.Elements(), e => e.Value, d => d.Name, (e, dSeq) => {
    var d = dSeq.Single();
    return new { e, d };
});

GroupJoin resultSelector принимает два аргумента: левую клавишу и последовательность соответствующих правых клавиш. Вы можете вызвать исключение, если последовательность пуста; Одним из способов достижения этого было бы использование оператора Single.

1 голос
/ 24 февраля 2012

Я думаю, что это одно из мест, где вы можете использовать Композитные ключи .

, если вы используете ключевое слово equals для выполнения равенства при объединении.

из документации:

Вы создаете составной ключ как анонимный тип или имя, набранное с помощью значения, которые вы хотите сравнить. Если переменная запроса будет передаваемый через границы метода, используйте именованный тип, который переопределяет Equals и GetHashCode для ключа

...