2010-07-29 3 views
3

У меня есть три таблицы из набора данных ds.Выбор столбца левой левой колонны LINQ

var test0 = from a in ds.Tables[0].AsEnumerable() 
      select a["ID"].ToString(); 

test0 имеет следующие значения -

[0] "8" 
    [1] "9" 
    [2] "11" 
    [3] "2" 
    [4] "1" 

var test1 = from a in ds.Tables[1].AsEnumerable() 
      select a["SubscriptionID"].ToString(); 

test1 имеет эти -

[0] "25" 
    [1] "27" 
    [2] "4" 
    [3] "26" 
    [4] "5" 
    [5] "6" 
    [6] "1" 
    [7] "24" 
    [8] "23" 
    [9] "2" 
    [10] "9" 

var comTable1 = 
    from a in ds.Tables[0].AsEnumerable() 
    from b in ds.Tables[1].AsEnumerable() 
    .Where(bb => bb["SubscriptionID"].ToString() == a["ID"].ToString()) 
    .DefaultIfEmpty() 
    select b; 

comTable1 возвращает эти значения, которые являются правильными -

[0] null 
    [1] {System.Data.DataRow} 
    [2] null 
    [3] {System.Data.DataRow} 
    [4] {System.Data.DataRow} 

Проблема для меня в том, что если я хочу выбрать конкретное поле, он выдает сообщение «Ссылка на объект, не установленная на экземпляр объекта». в comTable2 со следующими кодами -

var comTable2 = 
    from a in ds.Tables[0].AsEnumerable() 
    from b in ds.Tables[1].AsEnumerable() 
    .Where(bb => bb["SubscriptionID"].ToString() == a["ID"].ToString()) 
    .DefaultIfEmpty() 
    select b["SubscriptionID"]; 

Почему левое соединение в LINQ не возвращает другие пустые значения? Есть ли способ избежать этого?

Я спрашиваю это потому, что мои коды должны продолжать левые объединяться с другими таблицами, как -

var comTable = 
    from a in ds.Tables[0].AsEnumerable() 
    from b in ds.Tables[1].AsEnumerable() 
    .Where(bb => bb["SubscriptionID"].ToString() == a["ID"].ToString()) 
    .DefaultIfEmpty() 
    from c in ds.Tables[2].AsEnumerable() 
    .Where(cc => cc["ID"].ToString() == (b["GroupID"]??"null").ToString()) 
    .DefaultIfEmpty() 
    select c; 

Теперь я не мог получить что-нибудь от Ь и с.

Спасибо!

+0

oh мои бедные глаза :) Пожалуйста, отформатируйте свой код, используя параметры форматирования кода (маленькая двоичная кнопка в редакторе). –

+0

формат завершен, мой добрый поступок в течение дня. –

+0

Ну, это было весело. Четыре человека редактируют вопрос одновременно. –

ответ

3

Ну да, если вы попытаетесь разыменовать нулевое значение, вы получите . получите исключение. Попробуйте это:

var comTable2 = from a in ds.Tables[0].AsEnumerable() 
       from b in ds.Tables[1] 
          .AsEnumerable() 
          .Where(bb => bb["SubscriptionID"].ToString() 
            == a["ID"].ToString()) 
          .DefaultIfEmpty() 
       select b == null ? null : b["SubscriptionID"]; 

В основном условное выражение в конце оставит нулевые значения, где не было ни одного совпадения, и идентификатор подписки, если он сделал.

В вашем большом запросе вам все равно придется иметь дело с возможностью b, являющейся null. Вы определенно хотите здесь левое внешнее соединение, а не внутреннее соединение, заданное предложением LINQ join?

+0

Прохладный Джон. Это то, что мне нужно знать. На данный момент я хочу, чтобы левое внешнее соединение было определенно здесь. Кстати, ваш «C# in depth» - одна из моих любимых книг. Я читал его два раза с печатной копией и электронной копией. Надеюсь, вы опубликуете больше. – Don

Смежные вопросы