I'm using C# in Visual Studio and I have a table with an attribute set to allow nulls, I try to get a query excluding null values like so:
var playerQueryDel = (from p in DB.Jugadores
where p.goles != null
orderby p.goles
select new
{
tiros = p.tirosPorteria,
goles = p.goles,
nombre = p.nombreJugador
}
).ToList();
Where goles is an attribute of type int that accepts nulls and I know that there are some records in the database with null values in this attribute, the problem is that is returns "empty" values, for example trying this:
System.Diagnostics.Debug.WriteLine($"Testing: {playerQueryDel[0]}");
Prints this:
Testing:
I also try to print to know if it is emptry like so:
System.Diagnostics.Debug.WriteLine($"{playerQueryDel[0] == null}");
Prints false, what is the cause of this "not null but empty" value and is there a way to check without having to parse it to something else?
I'll upload more information if needed :)
A couple of things to try: Check that the list contains any items. Check the individual field in the result being returned.
System.Diagnostics.Debug.WriteLine($"Testing: {playerQueryDel.Count}");
System.Diagnostics.Debug.WriteLine($"Testing: {playerQueryDel[0].goles}");
Related
I would like to do something like what is described in this article. However, the article is from 2006, and requires extension methods the author wrote. I'm hoping there's something more built-in at this point.
The intent here is to save a method that contains only operations translatable to T-SQL and use it to assign specific properties in a LINQ-to-SQL select statement. If there's a radically different way to do this then what I've attempted, then that's also a valid answer.
How do I do it?
What I've Tried
I have a query sort of like this:
var theData = (
from inv in dc.Inventory
where inv.IsDeleted == false
join data in cdc.InventoryDatas
on inv.InvKey equals data.ReInvKey
where data.ReColKey == colKey
select new MyClass {
SerialNumber = inv.SerialNumber,
Data = InventoryData.DataExpression( data ),
Name = inv.Name,
}
);
Where InventoryData.DataExpression is defined as such:
public static Expression<Func<InventoryData, string>> DataExpression = (
d => d.TextData != null ? d.TextData
: d.IntegerData != null ? d.IntegerData.ToString()
: d.DecimalData != null ? d.DecimalData.ToString()
: d.DateData != null ? d.DateData.ToString()
: d.BooleanData != null ? d.BooleanData.ToString()
: null
);
But it's not quite right. How can I make this work?
This works just fine when select only data from one table, and when I don't combine other expressions in the right side of the assignment statement for the same property:
Data = InventoryData.DataExpression.Compile()( data )
as do
select InventoryData.CompiledDataExpression( data )
and
select data.GetData()
where CompiledDataExpression is defined as
public static Func<InventoryData, string> CompiledDataExpression
= InventoryData.DataExpression.Compile();
and GetData is defined as
public string GetData() {
// execute the compiled delegete on this InventoryData
var ret = InventoryData.CompiledDataExpression( this );
return ret;
}
However, the delegate is not actually compiled to T-SQL. Instead, whole objects of the type associated with the table are pulled, and then the delegate is executed upon them locally.
I get an error when I try the full query, which joins on other tables and assigns the delegate to just one of several properties, some of which pull data from the other tables.
objLst = objLst.FindAll(c => c.Emp_cod.Equals(string.Empty)
|| c.Emp_cod.Equals(null))
I am having a List of All Employees and New Employees who have been offered has emp_cod value null.
Now when i am trying to find New Employees using the above code it gives object reference error.
Emp_cod column is string defined as below when imported from SQL to DBML:
[Column(Storage = "_Emp_cod", DbType = "VarChar(10)")]
public string Emp_cod { get; set; }
You can try:
objLst = objLst.Where(c => String.IsNullOrEmpty(c.Emp_cod));
The reason you are getting the error is because you are trying to call instance method Equals on null object. You need to check for null first and then check for string empty.
objLst = objLst.FindAll(c => c.Emp_cod != null && c.Emp_cod.Equals(string.Empty));
Or better if you may use string.IsNullOrEmpty like Adrian's answer.
You may also try string.IsNullOrWhiteSpace if you want to check against, null, empty and white spaces, but only if you are using .Net 4.0 or higher
objLst = objLst.FindAll(c => string.IsNullOrWhiteSpace(c.Emp_code))
Hopefully this is an easy one. Is there a way to test for an "empty" field using DataRow? The following work fine for testing against a field with null values, unfortunately, the column I'm dealing with are either populated with data or are just "empty". Is there an approach in C# I'm missing? Thanks
if (Particle.Tables.Count == 0 || pDr.ItemArray[1].ToString() == "")
tblParticle.Append("No Data");
you can use stirng.isNullorEmpty to check for empty fields. String.isNullorEmpty
if (Particle.Tables.Count == 0 || string.isNullorEmpty(pDr.ItemArray[1].ToString()))
{
tblParticle.Append("No Data");
}
.
if (string.IsNullOrEmpty(pDr.ItemArray[1].ToString()))
{
tblParticle.Append("No Data");
}
else
{
//else do something else
}
checking for NULL will not hurt keep in mind that Null and Empty are two different things
See DataRow.IsNull method - it accepts a column name or index
and returns whether it is NULL
The following assumes we are talking about a string (VARCHAR/CHAR) column:
If you don't care if it is null or an empty string, and always want an empty string back, you can use DataRow["name"].ToString()
If you want your string object to become null or empty just like the field value, you can use DataRow["name"] as string
If you want to get an exception in case of NULL, you can use (string) DataRow["name"]
I have this block of code inside another LINQ statement.
VideoLinks = (from video in m.VideoLinks.DefaultIfEmpty(new VideoGallery())
orderby video.CreatedDate
select new VideoGallery()
{
Source = video.Source,
Type = video.Type,
Links = video.Links,
Title = video.Title
}).ToList()
unfortunately if dont use DefaultIfEmpty its through me an exception. If I use DefaultIfEmpty i give count as 1 for videolinks even if m.VideoLinks is null.
So now how can avoid getting count 1 if m.VideoLinks is null
DefaultIfEmpty is going to give you a default value. It counts as an item when you call ToList() on it...thus your count is 1.
This looks like you are using linq-to-objects, so you should add a where video != null
VideoLinks = (from video in m.VideoLinks
where video != null
orderby video.CreatedDate
select new VideoGallery()
{
Source = video.Source,
Type = video.Type,
Links = video.Links,
Title = video.Title
}).ToList()
wllmsaccnt is correct - your problem is the "DefaultIfEmpty" portion of your statement. By definition, you are requesting that there be at least one item in the collection, according to the definition of this method:
Returns the elements of the specified sequence or the specified value
in a singleton collection if the sequence is empty
I think the important question here is what exception are you receiving when you don't use DefaultIfEmpty? If you tell us that, perhaps we can help you avoid it...
Hi have a Linq Query to extract some information. Following is the part of it.
node = "DocumentClass";
AVariable="Something"
na="NA";
var documentClassesScript = (from documentClass in configparentXML.Descendants(node)
where documentClass.Attribute("Name").Value.Contains(AVariable)
select new ReadingXmlWithLinq
{
CustomStorageString = documentClass.Element("ValidationPluginAssociations") != null ? documentClass.Descendants("ValidationPluginAssociation").Attributes("CustomStorageString").Single().Value : na,
}
).Distinct();
In Some case i got following error
Sequence contains more than one
element
The reason is ValidationPluginAssociations contain more than one ValidationPluginAssociation. I need to distinct and get only one of them. Is there any way to get it.
if there is no need to have single object you can use First:
documentClass.Descendants("ValidationPluginAssociation")
.Attributes("CustomStorageString").First().Value