none
Снова LINQ RRS feed

  • Вопрос

  • Добрый день, уважаемые форумчане. Вот бьюсь с проблемой. Не получается решить.

    Имеем List<T> где T имеет вид

    class T
    {
     public string N;
     public List<S> x;
     public List<F> y;
    }

    и не могу получить данные LINQ запросом. Нужно по совпадению N перебрать List типов S и типов F по критерию. Точнее выборка работает но с одним НО. При нулл в результате поиска в одном из List анонимный обьект возвращаемый из запроса не создается вообще. Даже если есть значение в List<S> но нет совпадения в List<F> например то вернется нулл а не обьект, нулл. Как вернуть обьект подскажите пожалуйста. Вот кусок запроса.

    var data = from table in _calibrationTables.AsParallel()
                     where table.Name == tank
                     let selectedTable = table
                     from volume in selectedTable.BasicVolumeTable
                     where volume.Level == (int)level
                     from normalization in selectedTable.NormalizationTable
                     where
                                                     normalization.LowOrderDigit == LowOrderDigit &&
                                                     normalization.FromLevel <= (int)level &&
                                                     normalization.ToLevel > (int)level
    
                                                select
                                                    new
                                                    {
                                                            V = volume.Volume,
                                                            N = normalization.VolumeNormalization
                                                    };


    если volume.Volume или normalization.VolumeNormalization нулл то нулл весь анонимный обьект. Хотя данные нужно получить в любом случае.

    Спасибо.

    • Перемещено YatajgaEditor 14 ноября 2013 г. 6:53
    13 ноября 2013 г. 15:26

Ответы

  • переписал код как

                                    var data = (from table in _calibrationTables.AsParallel()
                                                where table.Name == tank
                                                let selectedTable = table
                                                select new
                                                {
                                                        V = selectedTable.BasicVolumeTable.Where(source => source.Level == (int)level)
                                                                                          .Select(source => source.Volume)
                                                                                          .DefaultIfEmpty(0F)
                                                                                          .Single(),
    
                                                        N = selectedTable.NormalizationTable.Where(source => source.LowOrderDigit == LowOrderDigit && source.FromLevel <= (int)level && source.ToLevel >= (int)level)
                                                                                            .Select(source => source.VolumeNormalization)
                                                                                            .DefaultIfEmpty(0F)
                                                                                            .Single() 
                                                }).Single();
    

    и пошло. Спасибо вам Brash_O  за ваше время и внимание  теме.
    • Помечено в качестве ответа Little_Cat_2003 14 ноября 2013 г. 11:33
    14 ноября 2013 г. 11:33

Все ответы

  • а так не работает?

    select
                                                    new
                                                    {
                                                            V = volume.Volume ?? "",
                                                            N = normalization.VolumeNormalization ?? ""
                                                    };

    14 ноября 2013 г. 4:58
  • Нет. Пробовал. Он в new вообще не попадает судя по перехвату брэкпоинтами, если normalization = null. В том то и дело что не могу поймать где он нулл получает.

    Пробовал сделать так

    var data = (from table in _calibrationTables.AsParallel()
                     where table.Name == tank
                     let selectedTable = table
                     from volume in selectedTable.BasicVolumeTable
                     where volume.Level == (int)level
    let v = volume.Check()
                     from normalization in selectedTable.NormalizationTable
                     where
                                                     normalization.LowOrderDigit == LowOrderDigit &&
                                                     normalization.FromLevel <= (int)level &&
                                                     normalization.ToLevel > (int)level
    
                     let n = normalization.Check()
                                                select
                                                    new
                                                    {
                                                            V = v,
                                                            N = n
                                                    }).Single();

    то есть контроллировать возвращаемое значение своим екст методом Check(){return value ?? new T;} до сбора в обьект - выкидывает ошибку "Sequence contains no elements" все равно,  как это побороть - не могу понять.



    14 ноября 2013 г. 6:43
  • var data = (from table in _calibrationTables.AsParallel()
                     where table.Name == tank
    select new {V = (from table.BasicVolumeTable
                     where volume.Level == (int)level).firstOrDefault(),
    N = (from table.NormalizationTable
                     where
                                                     normalization.LowOrderDigit == LowOrderDigit &&
                                                     normalization.FromLevel <= (int)level &&
                                                     normalization.ToLevel > (int)level)FirstOrDefault()
    }
    а так?
    14 ноября 2013 г. 7:04
  • Точнее так

    var data = (from table in _calibrationTables.AsParallel()
                                               where table.Name == tank
                                               select new {V = (from volume in table.BasicVolumeTable 
                                                             where volume.Level == (int)level select volume).FirstOrDefault(),
                                                                                                                      
                                                        N = (from normalization in table.NormalizationTable
                                                             where
                                                                normalization.LowOrderDigit == LowOrderDigit &&
                                                                normalization.FromLevel <= (int)level &&
                                                                normalization.ToLevel > (int)level select normalization).FirstOrDefault() 
                                                 }).Single();
    

    выдает {"Object reference not set to an instance of an object."} - таки опять не получено значение для N хотя V - есть и весь обьект опять нулл. :-(

    14 ноября 2013 г. 8:03
  • проверьте а для всех ли значений в таблице _callibrationTable есть значения в NormalizationTable и BasicVolumeTable, такое ощущени что в какой то из строк эти билицы равны null

    14 ноября 2013 г. 8:58
  • Понимаете, это как раз такой случай и есть. Да, он выполняет поиск для значения, которого может не оказаться в таблице. Вопрос как раз в том - как заблокировать появления нулл референс эксепшен в случае когда одно из 2 значений не найдено (целая и дробная части ) и вернуть дефолтовый 0.

    14 ноября 2013 г. 9:46
  • Попробуйте тогда поменять определение класса на что то в таком стиле

    class T
    {
     public string N;
     public List<S> x=new List<S>();
     public List<F> y=new List<F>();
    }это должно убрать эти ошибки
    14 ноября 2013 г. 9:53
  • К сожалению нет.


    {"Object reference not set to an instance of an object."}
    14 ноября 2013 г. 11:20
  • переписал код как

                                    var data = (from table in _calibrationTables.AsParallel()
                                                where table.Name == tank
                                                let selectedTable = table
                                                select new
                                                {
                                                        V = selectedTable.BasicVolumeTable.Where(source => source.Level == (int)level)
                                                                                          .Select(source => source.Volume)
                                                                                          .DefaultIfEmpty(0F)
                                                                                          .Single(),
    
                                                        N = selectedTable.NormalizationTable.Where(source => source.LowOrderDigit == LowOrderDigit && source.FromLevel <= (int)level && source.ToLevel >= (int)level)
                                                                                            .Select(source => source.VolumeNormalization)
                                                                                            .DefaultIfEmpty(0F)
                                                                                            .Single() 
                                                }).Single();
    

    и пошло. Спасибо вам Brash_O  за ваше время и внимание  теме.
    • Помечено в качестве ответа Little_Cat_2003 14 ноября 2013 г. 11:33
    14 ноября 2013 г. 11:33