DefaultIfEmpty для LINQ для DataTable? - PullRequest
1 голос
/ 02 августа 2011

У меня есть запрос 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 ]

1 голос
/ 02 августа 2011

Я бы рекомендовал удалить DefaultIfEmpty() в вашем общемQuery и добавить некоторую логику, когда 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",
   ....
}; 
1 голос
/ 02 августа 2011

Здесь есть две отдельные проблемы. Во-первых, 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
}; 

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

...