DefaultIfEmpty for LINQ to a DataTable?
I have a LINQ query written to pull at least one row from a datatable as follows:
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")
};
I then try to set the properties of a new instance of a class with the values in the LINQ query output:
var genInfo = new GeneralInformationType
{
AgentName = generalQuery.FirstOrDefault().AgentName,
AgentPhoneNumber = generalQuery.FirstOrDefault().AgentPhoneNumber,
AgentEmailAddress = generalQuery.FirstOrDefault().AgentEmailAddress
};
The problem I am running into is that occasionally there are no results in the query. This tries to set the value o开发者_开发技巧f the various strings in GeneralInformationType to null and causes exceptions. I tried various methods of DefaultIfEmpty, but can't figure out where to put it.
Any help would be appreciated.
Thanks, Rob
I would recommend removing DefaultIfEmpty()
in your generalQuery and adding some logic when generalQuery is empty like so:
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",
....
};
There are two separate problems here. First, DefaultIfEmpty
is going to effectively give you a sequence with a null DataRow
if the query doesn't return anything. That will then fail not when it tries to assign strings - but when in the Where
clause. You're then also using FirstOrDefault
which would normally return null if there are no matching entries.
I would personally remove DefaultIfEmpty
call, and put all the defaulting in the code for 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
};
Obviously change "Default" to whatever you want. If you have more specific requirements, please explain what you're trying to do and I'm sure we'll be able to accommodate them...
精彩评论