DefaultIfEmpty для LINQ для DataTable?

У меня есть запрос LINQ, написанный для извлечения по крайней мере одной строки из таблицы данных следующим образом:

var generalQuery =
      from contact in contacts.AsEnumerable().DefaultIfEmpty()
      where contact.Field<String>("CONTACT_TYPE").ToUpper() == "AGENT"
      select new
          {
          AgentName = contact.Field<String>("FIRST_NAME") + " " +
              contact.Field<String>("LAST_NAME"),
          AgentPhoneNumber = contact.Field<String>("PHONE"),
          AgentEmailAddress = contact.Field<String>("EMAIL")
          };

Затем я пытаюсь установить свойства нового экземпляра класса со значениями в выводе запроса LINQ:

var genInfo = new GeneralInformationType
{
    AgentName = generalQuery.FirstOrDefault().AgentName,
    AgentPhoneNumber = generalQuery.FirstOrDefault().AgentPhoneNumber,
    AgentEmailAddress = generalQuery.FirstOrDefault().AgentEmailAddress
}; 

Проблема, с которой я сталкиваюсь, заключается в том, что иногда в запросе нет результатов. Это пытается установить значение различных строк в GeneralInformationType равным нулю и вызывает исключения. Я пробовал различные методы DefaultIfEmpty, но не могу понять, где его поставить.

Любая помощь будет оценена.

Спасибо роб

2 ответа

Решение

Я бы порекомендовал удалить DefaultIfEmpty() в вашем GeneralQuery и добавление некоторой логики, когда generalQuery пусто, например:

var generalQuery =
      from contact in contacts.AsEnumerable()
      where contact.Field<String>("CONTACT_TYPE").ToUpper() == "AGENT"
      select new
          {
          AgentName = contact.Field<String>("FIRST_NAME") + " " +
              contact.Field<String>("LAST_NAME"),
          AgentPhoneNumber = contact.Field<String>("PHONE"),
          AgentEmailAddress = contact.Field<String>("EMAIL")
          };

var genInfo = new GeneralInformationType
{
    AgentName = generalQuery.Any() ? generalQuery.First().AgentName : "Default Name",
   ....
}; 

Здесь есть две отдельные проблемы. Первый, DefaultIfEmpty собирается эффективно дать вам последовательность с нулевым DataRow если запрос ничего не возвращает. В этом случае произойдет сбой не при попытке назначить строки, а при Where пункт. Вы тогда также используете FirstOrDefault который обычно возвращает ноль, если нет подходящих записей.

Я бы лично удалил DefaultIfEmpty позвоните и поместите все значения по умолчанию в коде для genInfo:

var generalQuery =
       from contact in contacts.AsEnumerable()
       where contact.Field<String>("CONTACT_TYPE").ToUpper() == "AGENT"
       select new
       {
           AgentName = contact.Field<String>("FIRST_NAME") + " " +
               contact.Field<String>("LAST_NAME"),
           AgentPhoneNumber = contact.Field<String>("PHONE"),
           AgentEmailAddress = contact.Field<String>("EMAIL")
       };

// Like using DefaultIfEmpty(...).First()
var result = generalQuery.FirstOrDefault() ?? 
        new { AgentName = "Default",
              AgentPhoneNumber = "Default",
              AgentEmailAddress = "Default" };

var genInfo = new GeneralInformationType
{
    AgentName = result.AgentName,
    AgentPhoneNumber = result.AgentPhoneNumber,
    AgentEmailAddress = result.AgentEmailAddress
}; 

Очевидно, измените "По умолчанию" на все, что вы хотите. Если у вас есть более конкретные требования, пожалуйста, объясните, что вы пытаетесь сделать, и я уверен, что мы сможем их удовлетворить...

Другие вопросы по тегам